auto import from //depot/cupcake/@135843
diff --git a/samples/AliasActivity/Android.mk b/samples/AliasActivity/Android.mk
new file mode 100644
index 0000000..a34e1bf
--- /dev/null
+++ b/samples/AliasActivity/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_PACKAGE_NAME := AliasActivity
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/samples/AliasActivity/AndroidManifest.xml b/samples/AliasActivity/AndroidManifest.xml
new file mode 100644
index 0000000..33ad326
--- /dev/null
+++ b/samples/AliasActivity/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.aliasactivity">
+    <application android:hasCode="false">
+        <activity android:name="android.app.AliasActivity" android:label="@string/app_label">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+            <meta-data android:name="android.app.alias"
+                    android:resource="@xml/alias" />
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/AliasActivity/res/values/strings.xml b/samples/AliasActivity/res/values/strings.xml
new file mode 100644
index 0000000..dd746e3
--- /dev/null
+++ b/samples/AliasActivity/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?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>
+    <string name="app_label">An Alias</string>
+</resources>
diff --git a/samples/AliasActivity/res/xml/alias.xml b/samples/AliasActivity/res/xml/alias.xml
new file mode 100644
index 0000000..3946333
--- /dev/null
+++ b/samples/AliasActivity/res/xml/alias.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<alias xmlns:android="http://schemas.android.com/apk/res/android">
+    <intent android:action="android.intent.action.VIEW"
+        android:data="http://www.google.com/">
+    </intent>
+</alias>
diff --git a/samples/ApiDemos/Android.mk b/samples/ApiDemos/Android.mk
new file mode 100644
index 0000000..5019c2f
--- /dev/null
+++ b/samples/ApiDemos/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples development
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += \
+        src/com/example/android/apis/app/IRemoteService.aidl \
+        src/com/example/android/apis/app/IRemoteServiceCallback.aidl \
+        src/com/example/android/apis/app/ISecondary.aidl \
+
+LOCAL_PACKAGE_NAME := ApiDemos
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the folloing include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
new file mode 100644
index 0000000..afcfbc8
--- /dev/null
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -0,0 +1,1705 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.apis">
+
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application android:name="ApiDemosApplication"
+            android:label="@string/activity_sample_code"
+            android:icon="@drawable/app_sample_code" >
+
+        <uses-library android:name="com.google.android.maps" />
+
+        <activity android:name="ApiDemos">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--      APPLICATION PACKAGE SAMPLES      -->
+        <!-- ************************************* -->
+
+        <!-- Activity Samples -->
+
+        <activity android:name=".app.HelloWorld" android:label="@string/activity_hello_world">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.DialogActivity"
+                android:label="@string/activity_dialog"
+                android:theme="@android:style/Theme.Dialog">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.CustomDialogActivity"
+                android:label="@string/activity_custom_dialog"
+                android:theme="@style/Theme.CustomDialog">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.TranslucentActivity"
+                android:label="@string/activity_translucent"
+                android:theme="@style/Theme.Translucent">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.TranslucentBlurActivity"
+                android:label="@string/activity_translucent_blur"
+                android:theme="@style/Theme.Transparent">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.SaveRestoreState"
+                android:label="@string/activity_save_restore"
+                android:windowSoftInputMode="stateVisible|adjustResize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.PersistentState"
+                android:label="@string/activity_persistent"
+                android:windowSoftInputMode="stateVisible|adjustResize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ReceiveResult" android:label="@string/activity_receive_result">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.SendResult">
+        </activity>
+
+        <activity android:name=".app.Forwarding" android:label="@string/activity_forwarding">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ForwardTarget">
+        </activity>
+
+        <activity android:name=".app.RedirectEnter" android:label="@string/activity_redirect">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.RedirectMain">
+        </activity>
+
+        <activity android:name=".app.RedirectGetter">
+        </activity>
+
+        <activity android:name=".app.CustomTitle"
+                android:label="@string/activity_custom_title"
+                android:windowSoftInputMode="stateVisible|adjustPan">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ReorderOnLaunch"
+                android:label="@string/activity_reorder">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name=".app.ReorderTwo" />
+        <activity android:name=".app.ReorderThree" />
+        <activity android:name=".app.ReorderFour" />
+        
+        <!-- Intent Samples -->
+
+        <activity android:name=".app.Intents" android:label="@string/activity_intents">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Service Samples -->
+
+        <service android:name=".app.LocalService" />
+
+        <activity android:name=".app.LocalServiceController" android:label="@string/activity_local_service_controller">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.LocalServiceBinding" android:label="@string/activity_local_service_binding">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".app.RemoteService" android:process=":remote">
+            <intent-filter>
+                <!-- These are the interfaces supported by the service, which
+                     you can bind to. -->
+                <action android:name="com.example.android.apis.app.IRemoteService" />
+                <action android:name="com.example.android.apis.app.ISecondary" />
+                <!-- This is an action code you can use to select the service
+                     without explicitly supplying the implementation class. -->
+                <action android:name="com.example.android.apis.app.REMOTE_SERVICE" />
+            </intent-filter>
+        </service>
+
+        <activity android:name=".app.RemoteServiceController" android:label="@string/activity_remote_service_controller">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.RemoteServiceBinding" android:label="@string/activity_remote_service_binding">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".app.ServiceStartArguments" />
+
+        <activity android:name=".app.ServiceStartArgumentsController" android:label="@string/activity_service_start_arguments_controller">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Alarm Samples -->
+
+        <receiver android:name=".app.OneShotAlarm" android:process=":remote" />
+
+        <receiver android:name=".app.RepeatingAlarm" android:process=":remote" />
+
+        <activity android:name=".app.AlarmController" android:label="@string/activity_alarm_controller">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".app.AlarmService_Service" android:process=":remote" />
+
+        <activity android:name=".app.AlarmService" android:label="@string/activity_alarm_service">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Instrumentation Samples -->
+
+        <activity android:name=".app.LocalSample" android:label="@string/activity_local_sample">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <!-- category android:name="android.intent.category.SAMPLE_CODE" /-->
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.ContactsFilter" android:label="@string/activity_contacts_filter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <!-- category android:name="android.intent.category.SAMPLE_CODE" /-->
+            </intent-filter>
+        </activity>
+
+
+        <!-- Notifications samples -->
+
+        <activity android:name=".app.NotifyWithText" android:label="App/Notification/NotifyWithText">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.IncomingMessage" android:label="App/Notification/IncomingMessage">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.IncomingMessageView" android:label="App/Notification/IncomingMessageView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.EMBED" />
+            </intent-filter>
+        </activity>
+
+        <!-- This is used to display a notification selected by the user
+             from StatusBarNotifications.  Note the configuration here so
+             that the activity layers on top of whatever the user is doing,
+             allowing them to press back to return. -->
+        <activity android:name=".app.NotificationDisplay"
+                android:theme="@style/Theme.Transparent"
+                android:taskAffinity=""
+                android:excludeFromRecents="true"
+                android:noHistory="true">
+        </activity>
+
+        <activity android:name=".app.StatusBarNotifications"
+                android:label="App/Notification/Status Bar"
+                android:launchMode="singleTop">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".app.NotifyingService" />
+
+        <activity android:name=".app.NotifyingController" android:label="App/Notification/Notifying Service Controller">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Dialog samples -->
+        <activity android:name=".app.AlertDialogSamples" android:label="@string/activity_alert_dialog">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Search Samples -->
+
+        <!-- This activity represents a "typical" activity in your application from which the -->
+        <!-- user would be allowed to invoke a search function.  As noted below, the definition -->
+        <!-- of android.app.default_searchable is more typically handled at the application -->
+        <!-- level, where it can serve as a default for all of your activities. -->
+
+        <activity android:name=".app.SearchInvoke"
+                  android:label="@string/search_invoke">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+
+            <!-- This metadata entry causes .app.SearchQueryResults to be the default context -->
+            <!-- whenever the user invokes search while in this Activity. -->
+            <meta-data android:name="android.app.default_searchable"
+                       android:value=".app.SearchQueryResults" />
+            
+            <!-- This is not the typical way to define android.app.default_searchable, -->
+            <!-- and we show it here only because we wish to confine the search demo to this -->
+            <!-- section of the ApiDemos application. -->
+            
+            <!-- For typical applications, it's simpler to define android.app.default_searchable -->
+            <!-- just once, at the application level, where it serves as a default for all of -->
+            <!-- the Activities in your package. -->
+        </activity>
+
+        <!-- This activity represents the "search" activity in your application, in which -->
+        <!-- search results are gathered and displayed. -->
+
+        <activity android:name=".app.SearchQueryResults"
+                  android:label="@string/search_query_results">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+            
+            <!-- This intent-filter identifies this activity as "searchable" -->
+            
+            <intent-filter>
+                <action android:name="android.intent.action.SEARCH" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            
+            <!-- This metadata entry provides further configuration details for searches -->
+            <!-- that are handled by this activity. -->
+            
+            <meta-data android:name="android.app.searchable"
+                       android:resource="@xml/searchable" />
+        </activity>
+
+        <!-- This provider declaration informs the Search Manager that you have a provider of -->
+        <!-- Search suggestions, and provides information about how to access it. -->
+        
+        <provider android:name=".app.SearchSuggestionSampleProvider"
+                  android:authorities="com.example.android.apis.SuggestionProvider" />
+
+        <!-- Shortcuts Samples -->
+
+        <!-- This section of sample code shows how your application can add shortcuts to -->
+        <!-- the launcher (home screen).  Shortcuts have a three step life cycle. -->
+        
+        <!-- 1.  Your application offers to provide shortcuts to the launcher.  When -->
+        <!--     the user installs a shortcut, an activity within your application -->
+        <!--     generates the actual shortcut and returns it to the launcher, where it -->
+        <!--     is shown to the user as an icon. -->
+        
+        <!-- 2.  Any time the user clicks on an installed shortcut, an intent is sent. -->
+        <!--     Typically this would then be handled as necessary by an activity within -->
+        <!--     your application. -->
+
+        <!-- 3.  The shortcut is deleted.  There is no notification to your application. -->
+
+        <!-- In order provide shortcuts from your application, you provide three things: -->
+
+        <!-- 1.  An intent-filter declaring your ability to provide shortcuts -->
+        <!-- 2.  Code within the activity to provide the shortcuts as requested -->
+        <!-- 3.  Code elsewhere within your activity, if appropriate, to receive -->
+        <!--     intents from the shortcut itself. -->
+
+        <activity android:name=".app.LauncherShortcuts"
+                  android:label="@string/shortcuts">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+
+        </activity>
+
+        <!-- It is recommended that you use an activity-alias to provide the "CREATE_SHORTCUT" -->
+        <!-- intent-filter.  This gives you a way to set the text (and optionally the -->
+        <!-- icon) that will be seen in the launcher's create-shortcut user interface. -->
+
+        <activity-alias android:name=".app.CreateShortcuts"
+            android:targetActivity=".app.LauncherShortcuts"
+            android:label="@string/sample_shortcuts">
+
+            <!--  This intent-filter allows your shortcuts to be created in the launcher. -->
+            <intent-filter>
+                <action android:name="android.intent.action.CREATE_SHORTCUT" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+
+        </activity-alias>
+
+        <!-- Menu Samples -->
+
+        <activity android:name=".app.MenuInflateFromXml" android:label="@string/menu_from_xml_title">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- Preferences Samples -->
+
+        <activity android:name=".app.PreferencesFromXml" android:label="@string/preferences_from_xml">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.PreferencesFromCode" android:label="@string/preferences_from_code">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.AdvancedPreferences" android:label="@string/advanced_preferences">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.LaunchingPreferences" android:label="@string/launching_preferences">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.PreferenceDependencies" android:label="@string/preference_dependencies">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".app.DefaultValues" android:label="@string/default_values">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+
+        <!-- Voice Recognition Samples -->
+
+        <activity android:name=".app.VoiceRecognition" android:label="@string/voice_recognition">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--        CONTENT PACKAGE SAMPLES        -->
+        <!-- ************************************* -->
+
+        <activity android:name=".content.StyledText" android:label="@string/activity_styled_text">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+                <category android:name="android.intent.category.EMBED" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".content.ReadAsset" android:label="@string/activity_read_asset">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+                <category android:name="android.intent.category.EMBED" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".content.ResourcesSample" android:label="@string/activity_resources">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--     OS PACKAGE SAMPLES                -->
+        <!-- ************************************* -->
+
+        <activity android:name=".os.MorseCode" android:label="OS/Morse Code">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".os.Sensors" android:label="OS/Sensors">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--     ANIMATION PACKAGE SAMPLES         -->
+        <!-- ************************************* -->
+
+        <activity android:name=".animation.Transition3d" android:label="Views/Animation/3D Transition">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--      VIEW/WIDGET PACKAGE SAMPLES      -->
+        <!-- ************************************* -->
+
+        <activity android:name=".view.ChronometerDemo" android:label="Views/Chronometer">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".view.WebView1" android:label="Views/WebView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.RelativeLayout1" android:label="Views/Layouts/RelativeLayout/1. Vertical">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.RelativeLayout2" android:label="Views/Layouts/RelativeLayout/2. Simple Form">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout1" android:label="Views/Layouts/LinearLayout/1. Vertical">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout2" android:label="Views/Layouts/LinearLayout/2. Vertical (Fill Screen)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout3" android:label="Views/Layouts/LinearLayout/3. Vertical (Padded)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout4" android:label="Views/Layouts/LinearLayout/4. Horizontal">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout5" android:label="Views/Layouts/LinearLayout/5. Simple Form">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout6" android:label="Views/Layouts/LinearLayout/6. Uniform Size">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout7" android:label="Views/Layouts/LinearLayout/7. Fill Parent">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout8" android:label="Views/Layouts/LinearLayout/8. Gravity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout9" android:label="Views/Layouts/LinearLayout/9. Layout Weight">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LinearLayout10" android:label="Views/Layouts/LinearLayout/10. Background Image">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+
+        <activity android:name=".view.RadioGroup1" android:label="Views/Radio Group">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ScrollView1" android:label="Views/Layouts/ScrollView/1. Short">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ScrollView2" android:label="Views/Layouts/ScrollView/2. Long">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs1" android:label="Views/Tabs/Content By Id">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs2" android:label="Views/Tabs/Content By Factory">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs3" android:label="Views/Tabs/Content By Intent">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.InternalSelectionScroll" android:label="Views/Layouts/ScrollView/3. Internal Selection">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout1" android:label="Views/Layouts/TableLayout/01. Basic">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout2" android:label="Views/Layouts/TableLayout/02. Empty Cells">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout3" android:label="Views/Layouts/TableLayout/03. Long Content">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout4" android:label="Views/Layouts/TableLayout/04. Stretchable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout5" android:label="Views/Layouts/TableLayout/05. Spanning and Stretchable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout6" android:label="Views/Layouts/TableLayout/06. More Spanning and Stretchable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout7" android:label="Views/Layouts/TableLayout/07. Column Collapse">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout8" android:label="Views/Layouts/TableLayout/08. Toggle Stretch">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout9" android:label="Views/Layouts/TableLayout/09. Toggle Shrink">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout10" android:label="Views/Layouts/TableLayout/10. Simple Form">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout11" android:label="Views/Layouts/TableLayout/11. Gravity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TableLayout12" android:label="Views/Layouts/TableLayout/12. Cell Spanning">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs1" android:label="Views/Tabs/Content By Id">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs2" android:label="Views/Tabs/Content By Factory">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Tabs3" android:label="Views/Tabs/Content By Intent">
+            <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" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Baseline2" android:label="Views/Layouts/Baseline/2. Bottom">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Baseline3" android:label="Views/Layouts/Baseline/3. Center">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Baseline4" android:label="Views/Layouts/Baseline/4. Everywhere">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Baseline6" android:label="Views/Layouts/Baseline/5. Multi-line">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Baseline7" android:label="Views/Layouts/Baseline/6. Relative">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.BaselineNested1" android:label="Views/Layouts/Baseline/Nested Example 1">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.BaselineNested2" android:label="Views/Layouts/Baseline/Nested Example 2">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.BaselineNested3" android:label="Views/Layouts/Baseline/Nested Example 3">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ScrollBar1" android:label="Views/ScrollBars/1. Basic">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ScrollBar2" android:label="Views/ScrollBars/2. Fancy">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ScrollBar3" android:label="Views/ScrollBars/3. Style">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Visibility1" android:label="Views/Visibility">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List1" android:label="Views/Lists/1. Array">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List2" android:label="Views/Lists/2. Cursor (People)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List3" android:label="Views/Lists/3. Cursor (Phones)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List4" android:label="Views/Lists/4. ListAdapter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List5" android:label="Views/Lists/5. Separators">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List6" android:label="Views/Lists/6. ListAdapter Collapsed">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List7" android:label="Views/Lists/7. Cursor (Phones)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List8" android:label="Views/Lists/8. Photos">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List9" android:label="Views/Lists/9. Array (Overlay)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List10" android:label="Views/Lists/10. Single choice list">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List11" android:label="Views/Lists/11. Multiple choice list">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List12" android:label="Views/Lists/12. Transcript">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List13" android:label="Views/Lists/13. Slow Adapter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.List14" android:label="Views/Lists/14. Efficient Adapter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ExpandableList1" android:label="Views/Expandable Lists/1. Custom Adapter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ExpandableList2" android:label="Views/Expandable Lists/2. Cursor (People)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ExpandableList3" android:label="Views/Expandable Lists/3. Simple Adapter">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.CustomView1"
+                android:label="Views/Custom"
+                android:theme="@android:style/Theme.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Gallery1" android:label="Views/Gallery/1. Photos">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Gallery2" android:label="Views/Gallery/2. People">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Spinner1" android:label="Views/Spinner">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Grid1" android:label="Views/Grid/1. Icon Grid">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Grid2" android:label="Views/Grid/2. Photo Grid">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ImageView1"
+                android:label="Views/ImageView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ImageSwitcher1"
+                android:label="Views/ImageSwitcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TextSwitcher1"
+                android:label="Views/TextSwitcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ImageButton1"
+                android:label="Views/ImageButton">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Animation1" android:label="Views/Animation/Shake">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Animation2" android:label="Views/Animation/Push">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation1" android:label="Views/Layout Animation/1. Grid Fade">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation2" android:label="Views/Layout Animation/2. List Cascade">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation3" android:label="Views/Layout Animation/3. Reverse Order">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation4" android:label="Views/Layout Animation/4. Randomize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation5" android:label="Views/Layout Animation/5. Grid Direction">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation6" android:label="Views/Layout Animation/6. Wave Scale">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.LayoutAnimation7" android:label="Views/Layout Animation/7. Nested Animations">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls1"
+                android:label="Views/Controls/1. Light Theme"
+                android:theme="@android:style/Theme.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls2" android:label="Views/Controls/2. Default Theme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Buttons1"
+                android:label="Views/Buttons">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.AutoComplete1" android:label="Views/Auto Complete/1. Screen Top">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.AutoComplete2" android:label="Views/Auto Complete/2. Screen Bottom">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.AutoComplete3" android:label="Views/Auto Complete/3. Scroll">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.AutoComplete4" android:label="Views/Auto Complete/4. Contacts">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.AutoComplete5" android:label="Views/Auto Complete/5. Contacts with Hint">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.AutoComplete6" android:label="Views/Auto Complete/6. Multiple items">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ProgressBar1" android:label="Views/Progress Bar/1. Incremental">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ProgressBar2" android:label="Views/Progress Bar/2. Smooth">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ProgressBar3" android:label="Views/Progress Bar/3. Dialogs">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.ProgressBar4" android:label="Views/Progress Bar/4. In Title Bar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.SeekBar1" android:label="Views/Seek Bar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.RatingBar1" android:label="Views/Rating Bar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Focus1" android:label="Views/Focus/1. Vertical">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Focus2" android:label="Views/Focus/2. Horizontal">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Focus3" android:label="Views/Focus/3. Circular">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.InternalSelectionFocus" android:label="Views/Focus/4. Internal Selection">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.DateWidgets1" android:label="Views/Date Widgets/1. Dialog">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.DateWidgets2" android:label="Views/Date Widgets/2. Inline">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.MapViewDemo" android:label="Views/MapView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.MapViewCompassDemo" android:label="Views/MapView and Compass">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--           GRAPHICS SAMPLES            -->
+        <!-- ************************************* -->
+
+        <activity android:name=".graphics.kube.Kube" android:label="Graphics/OpenGL ES/Kube"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Compass" android:label="Graphics/Compass">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.CameraPreview" android:label="Graphics/CameraPreview" android:screenOrientation="landscape">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.GLSurfaceViewActivity"
+                android:label="Graphics/OpenGL ES/GLSurfaceView"
+                android:theme="@android:style/Theme.NoTitleBar"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.TranslucentGLSurfaceViewActivity"
+                android:label="Graphics/OpenGL ES/Translucent GLSurfaceView"
+                android:theme="@style/Theme.Translucent"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name=".graphics.TriangleActivity"
+                android:label="Graphics/OpenGL ES/Textured Triangle"
+                android:theme="@android:style/Theme.NoTitleBar"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name=".graphics.spritetext.SpriteTextActivity"
+                android:label="Graphics/OpenGL ES/Sprite Text"
+                android:theme="@android:style/Theme.NoTitleBar"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name=".graphics.TouchRotateActivity"
+                android:label="Graphics/OpenGL ES/Touch Rotate"
+                android:theme="@android:style/Theme.NoTitleBar"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name=".graphics.PolyToPoly" android:label="Graphics/PolyToPoly">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.ScaleToFit" android:label="Graphics/ScaleToFit">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.RoundRects" android:label="Graphics/RoundRects">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.ShapeDrawable1" android:label="Graphics/Drawable/ShapeDrawable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.SurfaceViewOverlay"
+                android:label="Graphics/SurfaceView Overlay">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.TextAlign" android:label="Graphics/Text Align">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Arcs" android:label="Graphics/Arcs">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Patterns" android:label="Graphics/Patterns">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Clipping" android:label="Graphics/Clipping">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Layers" android:label="Graphics/Layers">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.UnicodeChart" android:label="Graphics/UnicodeChart">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.PathFillTypes" android:label="Graphics/PathFillTypes">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Pictures" android:label="Graphics/Pictures">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Vertices" android:label="Graphics/Vertices">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.AnimateDrawables" android:label="Graphics/AnimateDrawables">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.SensorTest" android:label="Graphics/SensorTest">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.AlphaBitmap" android:label="Graphics/AlphaBitmap">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Regions" android:label="Graphics/Regions">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Sweep" android:label="Graphics/Sweep">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.BitmapMesh" android:label="Graphics/BitmapMesh">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.MeasureText" android:label="Graphics/MeasureText">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Typefaces" android:label="Graphics/Typefaces">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.FingerPaint" android:label="Graphics/FingerPaint">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.ColorMatrixSample" android:label="Graphics/ColorMatrix">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.BitmapDecode" android:label="Graphics/BitmapDecode">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.CreateBitmap" android:label="Graphics/CreateBitmap">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.DrawPoints" android:label="Graphics/Points">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.TouchPaint" android:label="Graphics/Touch Paint"
+                android:theme="@style/Theme.Black"
+                android:configChanges="keyboard|keyboardHidden|navigation|orientation">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.BitmapPixels" android:label="Graphics/BitmapPixels">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.Xfermodes" android:label="Graphics/Xfermodes">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.PathEffects" android:label="Graphics/PathEffects">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".graphics.GradientDrawable1" android:label="Graphics/Drawable/GradientDrawable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--             MEDIA SAMPLES             -->
+        <!-- ************************************* -->
+
+        <activity android:name=".media.MediaPlayerDemo" android:label="Media/MediaPlayer">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".media.MediaPlayerDemo_Audio" android:label="Media/MediaPlayer">
+            <intent-filter>
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".media.MediaPlayerDemo_Video" android:label="Media/MediaPlayer">
+            <intent-filter>
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".media.VideoViewDemo" android:label="Media/VideoView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <!-- ************************************* -->
+        <!--      GADGET PACKAGE SAMPLES           -->
+        <!-- ************************************* -->
+
+        <receiver android:name=".gadget.ExampleGadgetProvider">
+            <meta-data android:name="android.gadget.provider"
+                    android:resource="@xml/gadget_provider" />
+            <intent-filter>
+                <action android:name="android.gadget.action.GADGET_UPDATE" />
+            </intent-filter>
+        </receiver>
+
+        <receiver android:name=".gadget.ExampleBroadcastReceiver" android:enabled="false">
+            <intent-filter>
+                <action android:name="android.intent.ACTION_TIMEZONE_CHANGED" />
+                <action android:name="android.intent.ACTION_TIME" />
+            </intent-filter>
+        </receiver>
+
+        <!-- ************************************* -->
+        <!--             OTHER SAMPLES             -->
+        <!-- ************************************* -->
+
+        <activity android:name=".text.Link" android:label="Text/Linkify">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".text.Marquee" android:label="Text/Marquee">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name=".text.LogTextBox1" android:label="Text/LogTextBox">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+    <instrumentation android:name=".app.LocalSampleInstrumentation"
+        android:targetPackage="com.example.android.apis"
+        android:label="Local Sample" />
+
+</manifest>
diff --git a/samples/ApiDemos/_index.html b/samples/ApiDemos/_index.html
new file mode 100755
index 0000000..b0d1c7b
--- /dev/null
+++ b/samples/ApiDemos/_index.html
@@ -0,0 +1,19 @@
+<p>The API Demos include sample code for many aspects of the Android APIs, from screen layout to Intent resolution.
+</p>
+
+<dl>
+    <dt><a href="src/com/example/android/apis/app/index.html">App</a></dt>
+    <dd></dd>
+
+    <dt><a href="src/com/example/android/apis/content/index.html">Content</a></dt>
+    <dd></dd>
+    
+    <dt><a href="src/com/example/android/apis/view/index.html">View</a></dt>
+    <dd></dd>
+    
+    <dt><a href="src/com/example/android/apis/graphics/index.html">Graphics</a></dt>
+    <dd></dd>
+
+    <dt><a href="src/com/example/android/apis/text/index.html">Text</a></dt>
+    <dd></dd>
+</dl>
diff --git a/samples/ApiDemos/assets/fonts/samplefont.ttf b/samples/ApiDemos/assets/fonts/samplefont.ttf
new file mode 100644
index 0000000..49f1c62
--- /dev/null
+++ b/samples/ApiDemos/assets/fonts/samplefont.ttf
Binary files differ
diff --git a/samples/ApiDemos/assets/read_asset.txt b/samples/ApiDemos/assets/read_asset.txt
new file mode 100644
index 0000000..ff9c023
--- /dev/null
+++ b/samples/ApiDemos/assets/read_asset.txt
@@ -0,0 +1,3 @@
+This text is stored in a raw Asset.
+
+It was read and placed into the TextView here.
diff --git a/samples/ApiDemos/res/anim/cycle_7.xml b/samples/ApiDemos/res/anim/cycle_7.xml
new file mode 100644
index 0000000..02fb699
--- /dev/null
+++ b/samples/ApiDemos/res/anim/cycle_7.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+
+<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />
diff --git a/samples/ApiDemos/res/anim/fade.xml b/samples/ApiDemos/res/anim/fade.xml
new file mode 100644
index 0000000..78b193d
--- /dev/null
+++ b/samples/ApiDemos/res/anim/fade.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+       android:interpolator="@android:anim/accelerate_interpolator"
+       android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="100" />
diff --git a/samples/ApiDemos/res/anim/hyperspace_in.xml b/samples/ApiDemos/res/anim/hyperspace_in.xml
new file mode 100644
index 0000000..8d0cc56
--- /dev/null
+++ b/samples/ApiDemos/res/anim/hyperspace_in.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android" android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" android:startOffset="1200" />
diff --git a/samples/ApiDemos/res/anim/hyperspace_out.xml b/samples/ApiDemos/res/anim/hyperspace_out.xml
new file mode 100644
index 0000000..83fef33
--- /dev/null
+++ b/samples/ApiDemos/res/anim/hyperspace_out.xml
@@ -0,0 +1,54 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
+
+	<scale 
+		android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+		android:fromXScale="1.0" 
+		android:toXScale="1.4" 
+		android:fromYScale="1.0" 
+		android:toYScale="0.6" 
+		android:pivotX="50%"
+		android:pivotY="50%"
+		android:fillAfter="false"
+		android:duration="700" />
+
+
+	<set 
+		android:interpolator="@android:anim/accelerate_interpolator"
+                android:startOffset="700">
+		
+		<scale
+			android:fromXScale="1.4" 
+			android:toXScale="0.0"
+		        android:fromYScale="0.6"
+	 		android:toYScale="0.0" 
+	 		android:pivotX="50%" 
+	 		android:pivotY="50%" 
+	 		android:duration="400" />
+ 		
+		<rotate 
+			android:fromDegrees="0" 
+			android:toDegrees="-45"
+	 		android:toYScale="0.0" 
+	 		android:pivotX="50%" 
+	 		android:pivotY="50%"
+	 		android:duration="400" />
+	</set>
+
+</set>
+
diff --git a/samples/ApiDemos/res/anim/layout_animation_row_left_slide.xml b/samples/ApiDemos/res/anim/layout_animation_row_left_slide.xml
new file mode 100644
index 0000000..9c6a459
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_animation_row_left_slide.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:delay="10%"
+        android:animation="@anim/slide_left" />
diff --git a/samples/ApiDemos/res/anim/layout_animation_row_right_slide.xml b/samples/ApiDemos/res/anim/layout_animation_row_right_slide.xml
new file mode 100644
index 0000000..156f09a
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_animation_row_right_slide.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:delay="10%"
+        android:animationOrder="reverse"
+        android:animation="@anim/slide_right" />
diff --git a/samples/ApiDemos/res/anim/layout_animation_table.xml b/samples/ApiDemos/res/anim/layout_animation_table.xml
new file mode 100644
index 0000000..efebe84
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_animation_table.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:delay="50%"
+        android:animation="@anim/slide_top_to_bottom" />
diff --git a/samples/ApiDemos/res/anim/layout_bottom_to_top_slide.xml b/samples/ApiDemos/res/anim/layout_bottom_to_top_slide.xml
new file mode 100644
index 0000000..e7cb4bd
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_bottom_to_top_slide.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:delay="30%"
+        android:animationOrder="reverse"
+        android:animation="@anim/slide_right" />
diff --git a/samples/ApiDemos/res/anim/layout_grid_fade.xml b/samples/ApiDemos/res/anim/layout_grid_fade.xml
new file mode 100644
index 0000000..00d3584
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_grid_fade.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:rowDelay="50%"
+        android:directionPriority="column"
+        android:animation="@anim/fade" />
diff --git a/samples/ApiDemos/res/anim/layout_grid_inverse_fade.xml b/samples/ApiDemos/res/anim/layout_grid_inverse_fade.xml
new file mode 100644
index 0000000..0a68437
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_grid_inverse_fade.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:columnDelay="0.5"
+        android:directionPriority="row"
+        android:direction="right_to_left|bottom_to_top"
+        android:animation="@anim/fade" />
diff --git a/samples/ApiDemos/res/anim/layout_random_fade.xml b/samples/ApiDemos/res/anim/layout_random_fade.xml
new file mode 100644
index 0000000..0034676
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_random_fade.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:delay="0.5"
+        android:animationOrder="random"
+        android:animation="@anim/fade" />
diff --git a/samples/ApiDemos/res/anim/layout_wave_scale.xml b/samples/ApiDemos/res/anim/layout_wave_scale.xml
new file mode 100644
index 0000000..2cdd19d
--- /dev/null
+++ b/samples/ApiDemos/res/anim/layout_wave_scale.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:rowDelay="75%"
+        android:columnDelay="0%"
+        android:directionPriority="none"
+        android:animation="@anim/wave_scale" />
diff --git a/samples/ApiDemos/res/anim/push_left_in.xml b/samples/ApiDemos/res/anim/push_left_in.xml
new file mode 100644
index 0000000..894d222
--- /dev/null
+++ b/samples/ApiDemos/res/anim/push_left_in.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="300"/>
+	<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />
+</set>
diff --git a/samples/ApiDemos/res/anim/push_left_out.xml b/samples/ApiDemos/res/anim/push_left_out.xml
new file mode 100644
index 0000000..28802d2
--- /dev/null
+++ b/samples/ApiDemos/res/anim/push_left_out.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="300"/>
+	<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />
+</set>
diff --git a/samples/ApiDemos/res/anim/push_up_in.xml b/samples/ApiDemos/res/anim/push_up_in.xml
new file mode 100644
index 0000000..a2f47e9
--- /dev/null
+++ b/samples/ApiDemos/res/anim/push_up_in.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="300"/>
+	<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />
+</set>
diff --git a/samples/ApiDemos/res/anim/push_up_out.xml b/samples/ApiDemos/res/anim/push_up_out.xml
new file mode 100644
index 0000000..2803435
--- /dev/null
+++ b/samples/ApiDemos/res/anim/push_up_out.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<translate android:fromYDelta="0" android:toYDelta="-100%p" android:duration="300"/>
+	<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />
+</set>
diff --git a/samples/ApiDemos/res/anim/shake.xml b/samples/ApiDemos/res/anim/shake.xml
new file mode 100644
index 0000000..80eb451
--- /dev/null
+++ b/samples/ApiDemos/res/anim/shake.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+
+<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="1000" android:interpolator="@anim/cycle_7" />
diff --git a/samples/ApiDemos/res/anim/slide_left.xml b/samples/ApiDemos/res/anim/slide_left.xml
new file mode 100644
index 0000000..8760491
--- /dev/null
+++ b/samples/ApiDemos/res/anim/slide_left.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
+    <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="150" />
+</set>
diff --git a/samples/ApiDemos/res/anim/slide_right.xml b/samples/ApiDemos/res/anim/slide_right.xml
new file mode 100644
index 0000000..7aaacdb
--- /dev/null
+++ b/samples/ApiDemos/res/anim/slide_right.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
+    <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="150" />
+</set>
diff --git a/samples/ApiDemos/res/anim/slide_top_to_bottom.xml b/samples/ApiDemos/res/anim/slide_top_to_bottom.xml
new file mode 100644
index 0000000..a548181
--- /dev/null
+++ b/samples/ApiDemos/res/anim/slide_top_to_bottom.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
+    <translate android:fromYDelta="-100%" android:toXDelta="0" android:duration="100" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="50" />
+</set>
diff --git a/samples/ApiDemos/res/anim/wave_scale.xml b/samples/ApiDemos/res/anim/wave_scale.xml
new file mode 100644
index 0000000..ea4eaf2
--- /dev/null
+++ b/samples/ApiDemos/res/anim/wave_scale.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
+    <alpha
+        android:fromAlpha="0.0"
+        android:toAlpha="1.0"
+        android:duration="100" />
+    <scale
+        android:fromXScale="0.5" android:toXScale="1.5"
+        android:fromYScale="0.5" android:toYScale="1.5"
+        android:pivotX="50%" android:pivotY="50%"
+        android:duration="200" />
+    <scale 
+        android:fromXScale="1.5" android:toXScale="1.0"
+        android:fromYScale="1.5" android:toYScale="1.0"
+        android:pivotX="50%" android:pivotY="50%"
+        android:startOffset="200"
+        android:duration="100" />
+</set>
diff --git a/samples/ApiDemos/res/drawable/alert_dialog_icon.png b/samples/ApiDemos/res/drawable/alert_dialog_icon.png
new file mode 100644
index 0000000..0a7de04
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/alert_dialog_icon.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/animated_gif.gif b/samples/ApiDemos/res/drawable/animated_gif.gif
new file mode 100644
index 0000000..51baf15
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/animated_gif.gif
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/app_sample_code.png b/samples/ApiDemos/res/drawable/app_sample_code.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/app_sample_code.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/arrow_down_float.png b/samples/ApiDemos/res/drawable/arrow_down_float.png
new file mode 100644
index 0000000..bfe0ce6
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/arrow_down_float.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/arrow_up_float.png b/samples/ApiDemos/res/drawable/arrow_up_float.png
new file mode 100644
index 0000000..77673ef
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/arrow_up_float.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/balloons.jpg b/samples/ApiDemos/res/drawable/balloons.jpg
new file mode 100644
index 0000000..6a90b92
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/balloons.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/beach.jpg b/samples/ApiDemos/res/drawable/beach.jpg
new file mode 100644
index 0000000..ae9794f
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/beach.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/black_box.xml b/samples/ApiDemos/res/drawable/black_box.xml
new file mode 100644
index 0000000..7772d56
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/black_box.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#1e000000"/>
+    <padding android:left="1dp" android:top="1dp"
+            android:right="1dp" android:bottom="1dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/black_opaque_box.xml b/samples/ApiDemos/res/drawable/black_opaque_box.xml
new file mode 100644
index 0000000..ba43f01
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/black_opaque_box.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#56000000"/>
+    <padding android:left="1dp" android:top="1dp"
+            android:right="1dp" android:bottom="1dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/box.xml b/samples/ApiDemos/res/drawable/box.xml
new file mode 100644
index 0000000..825de84
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/box.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+*/
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#00000000"/>
+    <stroke android:width="1dp" color="#ff000000"/>
+    <padding android:left="1dp" android:top="1dp"
+        android:right="1dp" android:bottom="1dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/button.9.png b/samples/ApiDemos/res/drawable/button.9.png
new file mode 100644
index 0000000..f6da7e5
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/button.9.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/circular_progress.xml b/samples/ApiDemos/res/drawable/circular_progress.xml
new file mode 100644
index 0000000..1d76f57
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/circular_progress.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:drawable="@drawable/progress_circular_background" />
+
+    <item><rotate
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fromDegrees="0"
+        android:toDegrees="360"
+        android:drawable="@drawable/progress_particle" />
+    </item>
+</layer-list>
+
diff --git a/samples/ApiDemos/res/drawable/filled_box.xml b/samples/ApiDemos/res/drawable/filled_box.xml
new file mode 100644
index 0000000..75d15a0
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/filled_box.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+*/
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#f0600000"/>
+    <stroke android:width="3dp" color="#ffff8080"/>
+    <corners android:radius="3dp" />
+    <padding android:left="10dp" android:top="10dp"
+        android:right="10dp" android:bottom="10dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/frog.gif b/samples/ApiDemos/res/drawable/frog.gif
new file mode 100644
index 0000000..9c20748
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/frog.gif
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_background_1.xml b/samples/ApiDemos/res/drawable/gallery_background_1.xml
new file mode 100644
index 0000000..a82794e
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_background_1.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/black_opaque_box" />
+    <item android:drawable="@drawable/black_box" />
+</selector>
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_1.jpg b/samples/ApiDemos/res/drawable/gallery_photo_1.jpg
new file mode 100644
index 0000000..a2581fe
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_1.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_2.jpg b/samples/ApiDemos/res/drawable/gallery_photo_2.jpg
new file mode 100644
index 0000000..82ba3a8
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_2.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_3.jpg b/samples/ApiDemos/res/drawable/gallery_photo_3.jpg
new file mode 100644
index 0000000..2a83021
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_3.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_4.jpg b/samples/ApiDemos/res/drawable/gallery_photo_4.jpg
new file mode 100644
index 0000000..70a1c55
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_4.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_5.jpg b/samples/ApiDemos/res/drawable/gallery_photo_5.jpg
new file mode 100644
index 0000000..dc3f677
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_5.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_6.jpg b/samples/ApiDemos/res/drawable/gallery_photo_6.jpg
new file mode 100644
index 0000000..2e113a0
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_6.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_7.jpg b/samples/ApiDemos/res/drawable/gallery_photo_7.jpg
new file mode 100644
index 0000000..bc30297
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_7.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/gallery_photo_8.jpg b/samples/ApiDemos/res/drawable/gallery_photo_8.jpg
new file mode 100644
index 0000000..dc3aa85
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/gallery_photo_8.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/ic_popup_reminder.png b/samples/ApiDemos/res/drawable/ic_popup_reminder.png
new file mode 100755
index 0000000..4f2b82c
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/ic_popup_reminder.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/icon48x48_1.png b/samples/ApiDemos/res/drawable/icon48x48_1.png
new file mode 100644
index 0000000..d3b8125
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/icon48x48_1.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/icon48x48_2.png b/samples/ApiDemos/res/drawable/icon48x48_2.png
new file mode 100755
index 0000000..84af2a2
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/icon48x48_2.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/line.xml b/samples/ApiDemos/res/drawable/line.xml
new file mode 100644
index 0000000..b3707ff
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/line.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
+    <stroke android:width="1dp" android:color="#FF000000"
+            android:dashWidth="1dp" android:dashGap="2dp" />
+    <size android:height="5dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/photo1.jpg b/samples/ApiDemos/res/drawable/photo1.jpg
new file mode 100644
index 0000000..825682b
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/photo1.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/photo2.jpg b/samples/ApiDemos/res/drawable/photo2.jpg
new file mode 100644
index 0000000..a1c8b55
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/photo2.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/photo3.jpg b/samples/ApiDemos/res/drawable/photo3.jpg
new file mode 100644
index 0000000..44b671e
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/photo3.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/photo4.jpg b/samples/ApiDemos/res/drawable/photo4.jpg
new file mode 100644
index 0000000..2483bb9
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/photo4.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/photo5.jpg b/samples/ApiDemos/res/drawable/photo5.jpg
new file mode 100644
index 0000000..250b085
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/photo5.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/photo6.jpg b/samples/ApiDemos/res/drawable/photo6.jpg
new file mode 100644
index 0000000..6c3c956
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/photo6.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/picture_frame.png b/samples/ApiDemos/res/drawable/picture_frame.png
new file mode 100644
index 0000000..ba71570
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/picture_frame.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/progress_circular_background.png b/samples/ApiDemos/res/drawable/progress_circular_background.png
new file mode 100644
index 0000000..7c637fd
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/progress_circular_background.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/progress_particle.png b/samples/ApiDemos/res/drawable/progress_particle.png
new file mode 100644
index 0000000..9160108
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/progress_particle.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/robot.png b/samples/ApiDemos/res/drawable/robot.png
new file mode 100644
index 0000000..8a9e698
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/robot.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_0.jpg b/samples/ApiDemos/res/drawable/sample_0.jpg
new file mode 100644
index 0000000..9dd3bce
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_0.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_1.jpg b/samples/ApiDemos/res/drawable/sample_1.jpg
new file mode 100644
index 0000000..46d06e0
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_1.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_2.jpg b/samples/ApiDemos/res/drawable/sample_2.jpg
new file mode 100644
index 0000000..c23dd63
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_2.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_3.jpg b/samples/ApiDemos/res/drawable/sample_3.jpg
new file mode 100644
index 0000000..0f0d5b5
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_3.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_4.jpg b/samples/ApiDemos/res/drawable/sample_4.jpg
new file mode 100644
index 0000000..d28ce6f
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_4.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_5.jpg b/samples/ApiDemos/res/drawable/sample_5.jpg
new file mode 100644
index 0000000..2348c7d
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_5.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_6.jpg b/samples/ApiDemos/res/drawable/sample_6.jpg
new file mode 100644
index 0000000..a35fc0c
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_6.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_7.jpg b/samples/ApiDemos/res/drawable/sample_7.jpg
new file mode 100644
index 0000000..96a4879
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_7.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_0.jpg b/samples/ApiDemos/res/drawable/sample_thumb_0.jpg
new file mode 100644
index 0000000..5b641e8
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_0.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_1.jpg b/samples/ApiDemos/res/drawable/sample_thumb_1.jpg
new file mode 100644
index 0000000..630c3c5
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_1.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_2.jpg b/samples/ApiDemos/res/drawable/sample_thumb_2.jpg
new file mode 100644
index 0000000..fad840a
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_2.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_3.jpg b/samples/ApiDemos/res/drawable/sample_thumb_3.jpg
new file mode 100644
index 0000000..27e0359
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_3.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_4.jpg b/samples/ApiDemos/res/drawable/sample_thumb_4.jpg
new file mode 100644
index 0000000..4934f02
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_4.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_5.jpg b/samples/ApiDemos/res/drawable/sample_thumb_5.jpg
new file mode 100644
index 0000000..c9c7380
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_5.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_6.jpg b/samples/ApiDemos/res/drawable/sample_thumb_6.jpg
new file mode 100644
index 0000000..0e2f3e4
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_6.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/sample_thumb_7.jpg b/samples/ApiDemos/res/drawable/sample_thumb_7.jpg
new file mode 100644
index 0000000..bf82c5d
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/sample_thumb_7.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/scrollbar_state2.png b/samples/ApiDemos/res/drawable/scrollbar_state2.png
new file mode 100755
index 0000000..012f737
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/scrollbar_state2.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/scrollbar_vertical_thumb.xml b/samples/ApiDemos/res/drawable/scrollbar_vertical_thumb.xml
new file mode 100644
index 0000000..4d80454
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/scrollbar_vertical_thumb.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient android:startColor="#3333FF" android:endColor="#8080FF"
+            android:angle="0"/>
+    <corners android:radius="6dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/scrollbar_vertical_track.xml b/samples/ApiDemos/res/drawable/scrollbar_vertical_track.xml
new file mode 100644
index 0000000..b3ad842
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/scrollbar_vertical_track.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient android:startColor="#505050" android:endColor="#C0C0C0"
+            android:angle="0"/>
+    <corners android:radius="0dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/shape_1.xml b/samples/ApiDemos/res/drawable/shape_1.xml
new file mode 100644
index 0000000..ea30bcf
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/shape_1.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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#00000000"/>
+    <stroke android:width="2dp" android:color="#ff000000"/>
+    <padding android:left="1dp" android:top="1dp"
+            android:right="1dp" android:bottom="1dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/shape_2.xml b/samples/ApiDemos/res/drawable/shape_2.xml
new file mode 100644
index 0000000..23bcb36
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/shape_2.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FF0000FF"/>
+    <stroke android:width="4dp" android:color="#FFFFFFFF"
+            android:dashWidth="1dp" android:dashGap="2dp" />
+    <padding android:left="7dp" android:top="7dp"
+            android:right="7dp" android:bottom="7dp" />
+    <corners android:radius="4dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/shape_3.xml b/samples/ApiDemos/res/drawable/shape_3.xml
new file mode 100644
index 0000000..6822037
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/shape_3.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+    <solid android:color="#00000000"/>
+    <stroke android:width="4dp" android:color="#99000000"
+            android:dashWidth="4dp" android:dashGap="2dp" />
+    <padding android:left="7dp" android:top="7dp"
+            android:right="7dp" android:bottom="7dp" />
+    <corners android:radius="4dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/shape_4.xml b/samples/ApiDemos/res/drawable/shape_4.xml
new file mode 100644
index 0000000..0deb0d1
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/shape_4.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
+    <stroke android:width="1dp" android:color="#FF000000"
+            android:dashWidth="1dp" android:dashGap="2dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/shape_5.xml b/samples/ApiDemos/res/drawable/shape_5.xml
new file mode 100644
index 0000000..edd1d6f
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/shape_5.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF"
+            android:angle="270"/>
+    <padding android:left="7dp" android:top="7dp"
+            android:right="7dp" android:bottom="7dp" />
+    <corners android:radius="8dp" />
+</shape>
diff --git a/samples/ApiDemos/res/drawable/star_big_on.png b/samples/ApiDemos/res/drawable/star_big_on.png
new file mode 100644
index 0000000..510c8b2
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/star_big_on.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_happy.png b/samples/ApiDemos/res/drawable/stat_happy.png
new file mode 100644
index 0000000..3a8791b
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/stat_happy.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_neutral.png b/samples/ApiDemos/res/drawable/stat_neutral.png
new file mode 100644
index 0000000..1dc0594
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/stat_neutral.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_sad.png b/samples/ApiDemos/res/drawable/stat_sad.png
new file mode 100644
index 0000000..17d26de
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/stat_sad.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_sample.png b/samples/ApiDemos/res/drawable/stat_sample.png
new file mode 100644
index 0000000..1733042
--- /dev/null
+++ b/samples/ApiDemos/res/drawable/stat_sample.png
Binary files differ
diff --git a/samples/ApiDemos/res/layout/alarm_controller.xml b/samples/ApiDemos/res/layout/alarm_controller.xml
new file mode 100644
index 0000000..9ce4d72
--- /dev/null
+++ b/samples/ApiDemos/res/layout/alarm_controller.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/alarm_controller"/>
+
+    <Button android:id="@+id/one_shot"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/one_shot_alarm">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/start_repeating"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start_repeating_alarm" />
+
+    <Button android:id="@+id/stop_repeating"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/stop_repeating_alarm" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/alarm_service.xml b/samples/ApiDemos/res/layout/alarm_service.xml
new file mode 100644
index 0000000..e24369c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/alarm_service.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/alarm_service"/>
+
+    <Button android:id="@+id/start_alarm"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start_alarm_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop_alarm"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/stop_alarm_service" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/alert_dialog.xml b/samples/ApiDemos/res/layout/alert_dialog.xml
new file mode 100644
index 0000000..ddd5cb6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/alert_dialog.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates different uses of the android.app.AlertDialog.
+     See corresponding Java code com.example.android.apis.app.AlertDialogSamples.java. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:orientation="vertical">
+    <LinearLayout
+        android:layout_width="fill_parent" android:layout_height="fill_parent"
+        android:orientation="vertical">
+        <Button android:id="@+id/two_buttons"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_two_buttons"/>
+        <Button android:id="@+id/two_buttons2"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_two_buttons2"/>
+        <Button android:id="@+id/select_button"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_select_button"/>
+        <Button android:id="@+id/progress_button"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_progress_button"/>
+        <Button android:id="@+id/radio_button"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_single_choice"/>
+        <Button android:id="@+id/checkbox_button"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_multi_choice"/>
+        <Button android:id="@+id/text_entry_button"
+            android:layout_width="fill_parent" android:layout_height="wrap_content"
+            android:text="@string/alert_dialog_text_entry"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/alert_dialog_text_entry.xml b/samples/ApiDemos/res/layout/alert_dialog_text_entry.xml
new file mode 100644
index 0000000..adec305
--- /dev/null
+++ b/samples/ApiDemos/res/layout/alert_dialog_text_entry.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView 
+        android:id="@+id/username_view"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:text="@string/alert_dialog_username"
+        android:gravity="left"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+            
+    <EditText
+        android:id="@+id/username_edit"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:scrollHorizontally="true"
+        android:autoText="false"
+        android:capitalize="none"
+        android:gravity="fill_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+
+    <TextView
+        android:id="@+id/password_view"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:text="@string/alert_dialog_password"
+        android:gravity="left"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+            
+    <EditText
+        android:id="@+id/password_edit"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:scrollHorizontally="true"
+        android:autoText="false"
+        android:capitalize="none"
+        android:gravity="fill_horizontal"
+        android:password="true"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+        
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_1.xml b/samples/ApiDemos/res/layout/animation_1.xml
new file mode 100644
index 0000000..cd25e04
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_1.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:orientation="vertical"
+    android:padding="10dip"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+    
+    <TextView 
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="10dip"
+        android:text="@string/animation_1_instructions"
+    />
+    
+    <EditText android:id="@+id/pw"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:clickable="true"
+        android:singleLine="true"
+        android:password="true"
+    />
+
+    <Button android:id="@+id/login"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/googlelogin_login"
+    />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/animation_2.xml b/samples/ApiDemos/res/layout/animation_2.xml
new file mode 100644
index 0000000..9f37920
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_2.xml
@@ -0,0 +1,67 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:padding="10dip"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+    <ViewFlipper android:id="@+id/flipper"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:flipInterval="2000"
+                android:layout_marginBottom="20dip" >
+                <TextView
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:gravity="center_horizontal"
+                        android:textSize="26sp"
+                        android:text="@string/animation_2_text_1"/>
+                <TextView
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:gravity="center_horizontal"
+                        android:textSize="26sp"
+                        android:text="@string/animation_2_text_2"/>
+                <TextView
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:gravity="center_horizontal"
+                        android:textSize="26sp"
+                        android:text="@string/animation_2_text_3"/>
+                <TextView
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:gravity="center_horizontal"
+                        android:textSize="26sp"
+                        android:text="@string/animation_2_text_4"/>
+    </ViewFlipper>
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="5dip"
+        android:text="@string/animation_2_instructions"
+    />
+
+    <Spinner android:id="@+id/spinner"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+    />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/animations_main_screen.xml b/samples/ApiDemos/res/layout/animations_main_screen.xml
new file mode 100644
index 0000000..ee9e339
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animations_main_screen.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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:id="@+id/container"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <ListView
+        android:id="@android:id/list"
+        android:persistentDrawingCache="animation|scrolling"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layoutAnimation="@anim/layout_bottom_to_top_slide" />
+
+    <ImageView
+        android:id="@+id/picture"
+        android:scaleType="fitCenter"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:visibility="gone" />
+
+</FrameLayout>
diff --git a/samples/ApiDemos/res/layout/autocomplete_1.xml b/samples/ApiDemos/res/layout/autocomplete_1.xml
new file mode 100644
index 0000000..3c41926
--- /dev/null
+++ b/samples/ApiDemos/res/layout/autocomplete_1.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:orientation="vertical"
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_1_instructions" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_1_country" />
+
+        <AutoCompleteTextView android:id="@+id/edit"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_1_focus" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/autocomplete_2.xml b/samples/ApiDemos/res/layout/autocomplete_2.xml
new file mode 100644
index 0000000..6d4ee75
--- /dev/null
+++ b/samples/ApiDemos/res/layout/autocomplete_2.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+
+<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="bottom">
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_2_focus" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_2_country" />
+
+        <AutoCompleteTextView android:id="@+id/edit"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/autocomplete_3.xml b/samples/ApiDemos/res/layout/autocomplete_3.xml
new file mode 100644
index 0000000..e97535a
--- /dev/null
+++ b/samples/ApiDemos/res/layout/autocomplete_3.xml
@@ -0,0 +1,165 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_1" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_2" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_3" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_4" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_5" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_6" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_7" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_8" />
+
+         <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_1" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_2" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_3" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_4" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_5" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_6" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_7" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button_8" />
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/autocomplete_3_country" />
+
+            <AutoCompleteTextView android:id="@+id/edit"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_3_button" />
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/autocomplete_3_country" />
+
+            <AutoCompleteTextView android:id="@+id/edit2"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/autocomplete_4.xml b/samples/ApiDemos/res/layout/autocomplete_4.xml
new file mode 100644
index 0000000..97e5eb9
--- /dev/null
+++ b/samples/ApiDemos/res/layout/autocomplete_4.xml
@@ -0,0 +1,49 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_4_instructions" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_4_name" />
+
+        <AutoCompleteTextView android:id="@+id/edit"
+            android:completionThreshold="1"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_4_message" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/autocomplete_5.xml b/samples/ApiDemos/res/layout/autocomplete_5.xml
new file mode 100644
index 0000000..34f68c6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/autocomplete_5.xml
@@ -0,0 +1,45 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_5_instructions" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_5_name" />
+
+        <AutoCompleteTextView android:id="@+id/edit"
+            android:completionThreshold="1"
+            android:completionHint="@string/autocomplete_5_hint"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/autocomplete_6.xml b/samples/ApiDemos/res/layout/autocomplete_6.xml
new file mode 100644
index 0000000..24fbda1
--- /dev/null
+++ b/samples/ApiDemos/res/layout/autocomplete_6.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:orientation="vertical"
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_7_instructions" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/autocomplete_7_country" />
+
+        <MultiAutoCompleteTextView android:id="@+id/edit"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/autocomplete_7_focus" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_1.xml b/samples/ApiDemos/res/layout/baseline_1.xml
new file mode 100644
index 0000000..0f1c9f6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_1.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/baseline_1_label" />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/baseline_1_button" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:text="@string/baseline_1_bigger" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_2.xml b/samples/ApiDemos/res/layout/baseline_2.xml
new file mode 100644
index 0000000..8e323b6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_2.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="bottom"
+        android:text="@string/baseline_2_label" />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="bottom"
+        android:text="@string/baseline_2_button" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:textSize="20sp"
+        android:text="@string/baseline_2_bigger" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_3.xml b/samples/ApiDemos/res/layout/baseline_3.xml
new file mode 100644
index 0000000..c251703
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_3.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/baseline_3_explanation" />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_weight="1.0"
+        android:layout_height="0dip">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="3dip"
+            android:layout_gravity="center_vertical"
+            android:text="@string/baseline_3_label" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="3dip"
+            android:layout_gravity="center_vertical"
+            android:text="@string/baseline_3_button" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:textSize="20sp"
+            android:text="@string/baseline_3_bigger" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_4.xml b/samples/ApiDemos/res/layout/baseline_4.xml
new file mode 100644
index 0000000..5faa9da
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_4.xml
@@ -0,0 +1,55 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/baseline_4_label" />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_4_button" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:textSize="20sp"
+        android:text="@string/baseline_4_bigger" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/baseline_4_label_2" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="bottom"
+        android:text="@string/baseline_4_label_3" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_6.xml b/samples/ApiDemos/res/layout/baseline_6.xml
new file mode 100644
index 0000000..5418afb
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_6.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <EditText android:id="@+id/anchor"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:textSize="20sp"
+        android:text="@string/baseline_6_multi_line" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@id/anchor"
+        android:layout_alignRight="@id/anchor"
+        android:text="@string/baseline_6_baseline" />
+
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_7.xml b/samples/ApiDemos/res/layout/baseline_7.xml
new file mode 100644
index 0000000..2dc9439
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_7.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView android:id="@+id/anchor"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:textStyle="bold"
+        android:text="@string/baseline_7_fat" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignBaseline="@id/anchor"
+        android:layout_height="wrap_content"
+        android:text="@string/baseline_7_lean" />
+    
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_nested_1.xml b/samples/ApiDemos/res/layout/baseline_nested_1.xml
new file mode 100644
index 0000000..b940239
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_nested_1.xml
@@ -0,0 +1,85 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_nested_1_label" />
+
+    <!-- We want the middle textview of this vertical linear layout to
+      be baseline aligned with the others.-->
+    <LinearLayout
+            android:orientation="vertical"
+            android:baselineAlignedChildIndex="1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="5dip"
+            android:text="@string/baseline_nested_1_label" />
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_down_float"/>
+    </LinearLayout>
+
+
+    <!-- We want the third index textview of this vertical linear layout to
+      be baseline aligned with the others.-->
+    <LinearLayout
+            android:orientation="vertical"
+            android:baselineAlignedChildIndex="2"
+            android:layout_width="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_height="wrap_content">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="5dip"
+            android:text="@string/baseline_nested_1_label" />
+    </LinearLayout>
+
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_nested_1_label" />
+
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_nested_2.xml b/samples/ApiDemos/res/layout/baseline_nested_2.xml
new file mode 100644
index 0000000..5bc8361
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_nested_2.xml
@@ -0,0 +1,85 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_nested_1_label" />
+
+    <!-- We want the middle textview of this vertical linear layout to
+      be baseline aligned with the others.-->
+    <LinearLayout
+            android:orientation="vertical"
+            android:baselineAlignedChildIndex="1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="5dip"
+            android:text="@string/baseline_nested_1_label" />
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_down_float"/>
+    </LinearLayout>
+
+
+    <!-- We want the third index textview of this vertical linear layout to
+      be baseline aligned with the others.-->
+    <LinearLayout
+            android:orientation="horizontal"
+            android:baselineAlignedChildIndex="2"
+            android:layout_width="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_height="wrap_content">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="5dip"
+            android:text="@string/baseline_nested_1_label" />
+    </LinearLayout>
+
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_nested_1_label" />
+
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/baseline_nested_3.xml b/samples/ApiDemos/res/layout/baseline_nested_3.xml
new file mode 100644
index 0000000..c01c947
--- /dev/null
+++ b/samples/ApiDemos/res/layout/baseline_nested_3.xml
@@ -0,0 +1,96 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_nested_1_label" />
+
+    <!-- We want the middle textview of this vertical linear layout to
+      be baseline aligned with the others.-->
+    <LinearLayout
+            android:orientation="vertical"
+            android:baselineAlignedChildIndex="1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="5dip"
+            android:text="@string/baseline_nested_1_label" />
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_down_float"/>
+    </LinearLayout>
+
+
+    <!-- We'll point to the linear layout to baseline align by, which
+      in turn will point to a text view inside of it -->
+    <LinearLayout
+        android:orientation="vertical"
+                android:baselineAlignedChildIndex="1"
+                android:layout_width="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_height="wrap_content">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/arrow_up_float"/>
+        <LinearLayout
+                android:orientation="vertical"
+                android:baselineAlignedChildIndex="2"
+                android:layout_width="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_height="wrap_content">
+            <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/arrow_up_float"/>
+            <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/arrow_up_float"/>
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginRight="5dip"
+                    android:text="@string/baseline_nested_1_label"/>
+        </LinearLayout>
+    </LinearLayout>
+
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:layout_gravity="center_vertical"
+        android:text="@string/baseline_nested_1_label" />
+
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/buttons_1.xml b/samples/ApiDemos/res/layout/buttons_1.xml
new file mode 100644
index 0000000..dc657ef
--- /dev/null
+++ b/samples/ApiDemos/res/layout/buttons_1.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- Lots of buttons = need scrolling -->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+        
+        <!-- Regular sized buttons -->
+        <Button android:id="@+id/button_normal"
+            android:text="@string/buttons_1_normal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <!-- Small buttons -->
+        <Button android:id="@+id/button_small"
+            style="?android:attr/buttonStyleSmall"
+            android:text="@string/buttons_1_small"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <ToggleButton android:id="@+id/button_toggle"
+            android:text="@string/buttons_1_toggle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+            
+    </LinearLayout>
+    
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/chronometer.xml b/samples/ApiDemos/res/layout/chronometer.xml
new file mode 100644
index 0000000..b38c2b6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/chronometer.xml
@@ -0,0 +1,64 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <Chronometer android:id="@+id/chronometer"
+        android:format="@string/chronometer_initial_format"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="30dip"
+        android:paddingTop="30dip"
+        />
+
+    <Button android:id="@+id/start"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/chronometer_start">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/chronometer_stop">
+    </Button>
+
+    <Button android:id="@+id/reset"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/chronometer_reset">
+    </Button>
+
+    <Button android:id="@+id/set_format"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/chronometer_set_format">
+    </Button>
+
+    <Button android:id="@+id/clear_format"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/chronometer_clear_format">
+    </Button>
+
+</LinearLayout>
+
+
diff --git a/samples/ApiDemos/res/layout/contacts_filter.xml b/samples/ApiDemos/res/layout/contacts_filter.xml
new file mode 100644
index 0000000..e8d1615
--- /dev/null
+++ b/samples/ApiDemos/res/layout/contacts_filter.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<!-- Front-end for running application instrumentation demonstration.
+     See corresponding Java code com.android.sdk.app.ContactsFilter.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/contacts_filter"/>
+
+    <Button android:id="@+id/go"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/go">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/controls_1.xml b/samples/ApiDemos/res/layout/controls_1.xml
new file mode 100644
index 0000000..29658d7
--- /dev/null
+++ b/samples/ApiDemos/res/layout/controls_1.xml
@@ -0,0 +1,122 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+    
+        <Button android:id="@+id/button"
+            android:text="@string/controls_1_save"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    
+        <EditText android:id="@+id/edit"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+            
+        <CheckBox android:id="@+id/check1"
+            android:paddingBottom="24sp"
+	        android:paddingTop="24sp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/controls_1_checkbox_1" />
+    
+        <CheckBox android:id="@+id/check2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/controls_1_checkbox_2" />
+    
+        <RadioGroup
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+    
+            <RadioButton android:id="@+id/radio1"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/controls_1_radiobutton_1" />
+    
+            <RadioButton android:id="@+id/radio2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/controls_1_radiobutton_2" />
+    
+        </RadioGroup>
+    
+        <CheckBox android:id="@+id/star"
+            style="?android:attr/starStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/controls_1_star" />
+                            
+        <ToggleButton android:id="@+id/toggle1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+   
+        <ToggleButton android:id="@+id/toggle2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+             
+        <Spinner android:id="@+id/spinner1"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:drawSelectorOnTop="true"
+        />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dip"
+            android:text="@string/textColorPrimary"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:focusable="true"
+        />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dip"
+            android:text="@string/textColorSecondary"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textColor="?android:attr/textColorSecondary"
+            android:focusable="true"
+        />
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dip"
+            android:text="@string/textColorTertiary"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textColor="?android:attr/textColorTertiary"
+            android:focusable="true"
+        />
+
+        <TextView
+            style="?android:attr/listSeparatorTextViewStyle"
+            android:text="@string/listSeparatorTextViewStyle"
+            android:layout_marginTop="5dip"
+        />
+        
+    </LinearLayout>
+
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/custom_dialog_activity.xml b/samples/ApiDemos/res/layout/custom_dialog_activity.xml
new file mode 100644
index 0000000..d706018
--- /dev/null
+++ b/samples/ApiDemos/res/layout/custom_dialog_activity.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates an activity with a custom dialog theme.
+     See corresponding Java code com.android.sdk.app.CustomDialogActivity.java. -->
+
+<!-- This screen consists of a single text field that displays some text. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:gravity="center_vertical|center_horizontal"
+    android:text="@string/custom_dialog_activity_text"/>
diff --git a/samples/ApiDemos/res/layout/custom_title.xml b/samples/ApiDemos/res/layout/custom_title.xml
new file mode 100644
index 0000000..dbe8cb6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/custom_title.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates how to use a custom title.
+     See corresponding Java code com.example.android.apis.app.CustomTitle.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:id="@+id/screen"
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    <LinearLayout android:layout_width="fill_parent" 
+        android:layout_height="wrap_content"
+        android:baselineAligned="false">
+        <EditText android:id="@+id/left_text_edit"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxEms="10"
+            android:minEms="10"
+            android:layout_gravity="center_vertical"
+            android:text="@string/custom_title_left" />
+        <Button android:id="@+id/left_text_button"
+            android:layout_width="wrap_content" 
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:text="@string/custom_title_left_button"/>
+    </LinearLayout>
+    <LinearLayout android:layout_width="fill_parent" 
+        android:layout_height="wrap_content"
+        android:baselineAligned="false">
+        <EditText android:id="@+id/right_text_edit"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxEms="10"
+            android:minEms="10"
+            android:layout_gravity="center_vertical"
+            android:text="@string/custom_title_right" />
+        <Button android:id="@+id/right_text_button"
+            android:layout_width="wrap_content" 
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:text="@string/custom_title_right_button"/>
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/custom_title_1.xml b/samples/ApiDemos/res/layout/custom_title_1.xml
new file mode 100644
index 0000000..f794332
--- /dev/null
+++ b/samples/ApiDemos/res/layout/custom_title_1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates how to use a custom title.
+     See corresponding Java code com.example.android.apis.app.CustomTitle.java. -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:orientation="vertical">
+    <TextView android:id="@+id/left_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:text="@string/custom_title_left" />
+    <TextView android:id="@+id/right_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:text="@string/custom_title_right" />
+</RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/custom_view_1.xml b/samples/ApiDemos/res/layout/custom_view_1.xml
new file mode 100644
index 0000000..cac91ad
--- /dev/null
+++ b/samples/ApiDemos/res/layout/custom_view_1.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates defining custom views in a layout file. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res/com.example.android.apis"
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+    
+    <com.example.android.apis.view.LabelView
+            android:background="@drawable/red"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" 
+            app:text="Red"/>
+    
+    <com.example.android.apis.view.LabelView
+            android:background="@drawable/blue"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" 
+            app:text="Blue" app:textSize="20dp"/>
+    
+    <com.example.android.apis.view.LabelView
+            android:background="@drawable/green"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" 
+            app:text="Green" app:textColor="#ffffffff" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/date_widgets_example_1.xml b/samples/ApiDemos/res/layout/date_widgets_example_1.xml
new file mode 100644
index 0000000..b9db6a0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/date_widgets_example_1.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+        <TextView android:id="@+id/dateDisplay"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/date_widgets_example_dateDisplay_text"/>
+    </LinearLayout>
+
+    <Button android:id="@+id/pickDate"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/date_widgets_example_pickDate_text"/>
+
+    <Button android:id="@+id/pickTime"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/date_widgets_example_pickTime_text"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/date_widgets_example_2.xml b/samples/ApiDemos/res/layout/date_widgets_example_2.xml
new file mode 100644
index 0000000..50b182d
--- /dev/null
+++ b/samples/ApiDemos/res/layout/date_widgets_example_2.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<!-- example of using the time changed callback, with now visible 'set' button-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+
+    <TimePicker android:id="@+id/timePicker"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent"/>
+
+    <TextView android:id="@+id/dateDisplay"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="4dip"
+            android:text="@string/date_widgets_example_dateDisplay_text"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/dialog_activity.xml b/samples/ApiDemos/res/layout/dialog_activity.xml
new file mode 100644
index 0000000..88c4b07
--- /dev/null
+++ b/samples/ApiDemos/res/layout/dialog_activity.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates an activity with a dialog theme.
+     See corresponding Java code com.android.sdk.app.DialogActivity.java. -->
+
+<!-- This screen consists of a single text field that displays some text. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:gravity="center_vertical|center_horizontal"
+    android:text="@string/dialog_activity_text"/>
diff --git a/samples/ApiDemos/res/layout/focus_1.xml b/samples/ApiDemos/res/layout/focus_1.xml
new file mode 100644
index 0000000..12af0a9
--- /dev/null
+++ b/samples/ApiDemos/res/layout/focus_1.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="fill_parent"
+    android:orientation="vertical">
+
+    <TextView android:id="@+id/txtStatus"
+        android:text="@string/focus_1_message"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content" />
+
+    <ListView android:id="@+id/rssListView"
+        android:background="#7700CC00"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent" />
+
+   <WebView android:id="@+id/rssWebView"
+        android:background="#77CC0000"
+        android:layout_height="50dip"
+        android:layout_width="fill_parent"
+        android:focusable="false" />
+
+    <Button android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:text="@string/focus_1_placeholder" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/focus_2.xml b/samples/ApiDemos/res/layout/focus_2.xml
new file mode 100644
index 0000000..6351de2
--- /dev/null
+++ b/samples/ApiDemos/res/layout/focus_2.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="fill_parent"
+    android:orientation="horizontal">
+
+    <Button android:id="@+id/leftButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/focus_2_left"
+        android:nextFocusRight="@+id/rightButton"/>  <!-- jump over middle! -->
+
+    <Button android:id="@+id/centerButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/focus_2_jump" />
+
+    <Button android:id="@+id/rightButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="3dip"
+        android:text="@string/focus_2_right"/>
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/focus_3.xml b/samples/ApiDemos/res/layout/focus_3.xml
new file mode 100644
index 0000000..f08c3f8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/focus_3.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using nextLeft, nextRight, nextUp and nextDown to get
+     focus behavior that would be difficult with default focus calculation alg.-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dip">
+
+    <Button android:id="@+id/top"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_centerHorizontal="true"
+        android:nextFocusDown="@+id/bottom"
+        android:text="@string/focus_3_top"/>
+
+    <Button android:id="@+id/right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:nextFocusLeft="@+id/left"
+        android:text="@string/focus_3_right"/>
+
+    <Button android:id="@+id/bottom"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:nextFocusUp="@+id/top"
+        android:text="@string/focus_3_bottom"/>
+
+    <Button android:id="@+id/left"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_centerVertical="true"
+        android:nextFocusRight="@+id/right"
+        android:text="@string/focus_3_left"/>
+
+</RelativeLayout>
+
+
+
+
+
+
+
diff --git a/samples/ApiDemos/res/layout/forward_target.xml b/samples/ApiDemos/res/layout/forward_target.xml
new file mode 100644
index 0000000..6d56ae2
--- /dev/null
+++ b/samples/ApiDemos/res/layout/forward_target.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates receiving activity results.
+     See corresponding Java code com.android.sdk.app.ReceiveResult.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:text="@string/forward_target"/>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/forwarding.xml b/samples/ApiDemos/res/layout/forwarding.xml
new file mode 100644
index 0000000..a860d88
--- /dev/null
+++ b/samples/ApiDemos/res/layout/forwarding.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates receiving activity results.
+     See corresponding Java code com.android.sdk.app.ReceiveResult.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/forwarding"/>
+
+    <Button android:id="@+id/go"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/go">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/gadget_configure.xml b/samples/ApiDemos/res/layout/gadget_configure.xml
new file mode 100644
index 0000000..bc9f40d
--- /dev/null
+++ b/samples/ApiDemos/res/layout/gadget_configure.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    >
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/gadget_configure_instructions"
+    />
+
+    <EditText
+        android:id="@+id/gadget_prefix"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+    />
+
+    <Button
+        android:id="@+id/save_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@android:string/ok"
+    />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/gadget_provider.xml b/samples/ApiDemos/res/layout/gadget_provider.xml
new file mode 100644
index 0000000..49cf42f
--- /dev/null
+++ b/samples/ApiDemos/res/layout/gadget_provider.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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/gadget_text"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:textColor="#ff000000"
+/>
+
diff --git a/samples/ApiDemos/res/layout/gallery_1.xml b/samples/ApiDemos/res/layout/gallery_1.xml
new file mode 100644
index 0000000..40f3443
--- /dev/null
+++ b/samples/ApiDemos/res/layout/gallery_1.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<Gallery xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gallery"
+	android:layout_width="fill_parent"
+	android:layout_height="wrap_content"
+/>
+       
diff --git a/samples/ApiDemos/res/layout/gallery_2.xml b/samples/ApiDemos/res/layout/gallery_2.xml
new file mode 100644
index 0000000..37e5d11
--- /dev/null
+++ b/samples/ApiDemos/res/layout/gallery_2.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_marginBottom="10dip"
+        android:text="@string/gallery_2_text"
+    />
+
+    <Gallery android:id="@+id/gallery"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:spacing="16dp"
+    />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/google_login.xml b/samples/ApiDemos/res/layout/google_login.xml
new file mode 100644
index 0000000..9ab2f62
--- /dev/null
+++ b/samples/ApiDemos/res/layout/google_login.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates styled string resources.
+     See corresponding Java code com.android.sdk.content.StyledText -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <Button
+        android:id="@+id/login"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/googlelogin_login"
+        />
+
+    <Button
+        android:id="@+id/bad_login"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/googlelogin_bad_login"
+        />
+
+    <Button
+        android:id="@+id/clear"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/googlelogin_clear"
+        />
+
+    <TextView
+        android:id="@+id/username_label"
+        android:visibility="gone"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/googlelogin_user"/>
+
+    <TextView
+        android:id="@+id/username"
+        android:visibility="gone"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/google_login_username_text"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/grid_1.xml b/samples/ApiDemos/res/layout/grid_1.xml
new file mode 100644
index 0000000..ca60320
--- /dev/null
+++ b/samples/ApiDemos/res/layout/grid_1.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myGrid"
+	android:layout_width="fill_parent" 
+	android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:verticalSpacing="10dp"
+    
+    android:horizontalSpacing="10dp"
+    android:numColumns="auto_fit"
+    android:columnWidth="60dp"
+    android:stretchMode="columnWidth"
+    
+    android:gravity="center"
+    />
diff --git a/samples/ApiDemos/res/layout/grid_2.xml b/samples/ApiDemos/res/layout/grid_2.xml
new file mode 100644
index 0000000..4640ab6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/grid_2.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:id="@+id/myGrid"
+	android:layout_width="fill_parent" 
+	android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:verticalSpacing="10dp"
+    
+    android:horizontalSpacing="10dp"
+    android:numColumns="auto_fit"
+    android:columnWidth="60dp"
+    android:stretchMode="columnWidth"
+    
+    android:gravity="center"
+    />
diff --git a/samples/ApiDemos/res/layout/hello_world.xml b/samples/ApiDemos/res/layout/hello_world.xml
new file mode 100644
index 0000000..364a83a
--- /dev/null
+++ b/samples/ApiDemos/res/layout/hello_world.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates basic application screen.
+     See corresponding Java code com.android.sdk.app.HelloWorld.java. -->
+
+<!-- This screen consists of a single text field that
+     displays our "Hello, World!" text. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:gravity="center_vertical|center_horizontal"
+    android:text="@string/hello_world"/>
diff --git a/samples/ApiDemos/res/layout/image_button_1.xml b/samples/ApiDemos/res/layout/image_button_1.xml
new file mode 100644
index 0000000..114163e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/image_button_1.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <ImageButton
+    	android:layout_width="100dip"
+    	android:layout_height="50dip"
+    	android:src="@android:drawable/sym_action_call" />
+    	
+   	<ImageButton
+    	android:layout_width="wrap_content"
+    	android:layout_height="wrap_content"
+    	android:src="@android:drawable/sym_action_chat" />	
+    	
+   	<ImageButton
+    	android:layout_width="wrap_content"
+    	android:layout_height="wrap_content"
+    	android:src="@android:drawable/sym_action_email" />	
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/image_switcher_1.xml b/samples/ApiDemos/res/layout/image_switcher_1.xml
new file mode 100644
index 0000000..d9cd080
--- /dev/null
+++ b/samples/ApiDemos/res/layout/image_switcher_1.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent"> 
+    
+    <ImageSwitcher android:id="@+id/switcher"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+    />
+    
+    <Gallery android:id="@+id/gallery"
+        android:background="#55000000"
+        android:layout_width="fill_parent"
+        android:layout_height="60dp"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        
+        android:gravity="center_vertical"
+        android:spacing="16dp"
+    />
+
+</RelativeLayout>
+   
diff --git a/samples/ApiDemos/res/layout/image_view_1.xml b/samples/ApiDemos/res/layout/image_view_1.xml
new file mode 100644
index 0000000..36b926d
--- /dev/null
+++ b/samples/ApiDemos/res/layout/image_view_1.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:orientation="vertical">
+        
+        <!-- The following four examples use a large image -->
+        <!-- 1. Non-scaled view, for reference -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_large_normal"/>
+        <ImageView
+            android:src="@drawable/sample_1"
+            android:adjustViewBounds="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+            
+        <!-- 2. Limit to at most 50x50 -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_large_at_most"/>
+        <ImageView
+            android:src="@drawable/sample_1"
+            android:adjustViewBounds="true"
+            android:maxWidth="50dip"
+            android:maxHeight="50dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+       <!-- 3. Limit to at most 70x70, with 10 pixels of padding all around -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_large_at_most_padded"/>
+       <ImageView
+            android:src="@drawable/sample_1"
+            android:background="#66FFFFFF"
+            android:adjustViewBounds="true"
+            android:maxWidth="70dip"
+            android:maxHeight="70dip"
+            android:padding="10dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+            
+        <!-- 4. Limit to exactly 70x70, with 10 pixels of padding all around -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_large_exactly_padded"/>
+        <ImageView
+            android:src="@drawable/sample_1"
+            android:background="#66FFFFFF"
+            android:scaleType="centerInside"
+            android:padding="10dip"
+            android:layout_width="70dip"
+            android:layout_height="70dip" />
+
+        <!-- Repeating the previous four examples with small image -->
+        <!-- 1. Non-scaled view, for reference -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_small_normal"/>
+        <ImageView
+            android:src="@drawable/stat_happy"
+            android:background="#FFFFFFFF"
+            android:adjustViewBounds="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+            
+        <!-- 2. Limit to at most 50x50 -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_small_at_most"/>
+        <ImageView
+            android:src="@drawable/stat_happy"
+            android:background="#FFFFFFFF"
+            android:adjustViewBounds="true"
+            android:maxWidth="50dip"
+            android:maxHeight="50dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+       <!-- 3. Limit to at most 70x70, with 10 pixels of padding all around -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_small_at_most_padded"/>
+        <ImageView
+            android:src="@drawable/stat_happy"
+            android:background="#FFFFFFFF"
+            android:adjustViewBounds="true"
+            android:maxWidth="70dip"
+            android:maxHeight="70dip"
+            android:padding="10dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+            
+        <!-- 4. Limit to exactly 70x70, with 10 pixels of padding all around -->
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:text="@string/image_view_small_exactly_padded"/>
+        <ImageView
+            android:src="@drawable/stat_happy"
+            android:background="#FFFFFFFF"
+            android:scaleType="centerInside"
+            android:padding="10dip"
+            android:layout_width="70dip"
+            android:layout_height="70dip" />
+
+ 
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/incoming_message.xml b/samples/ApiDemos/res/layout/incoming_message.xml
new file mode 100644
index 0000000..01ea04a
--- /dev/null
+++ b/samples/ApiDemos/res/layout/incoming_message.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <Button
+        android:id="@+id/notify"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/incoming_message_notify_text" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/incoming_message_info.xml b/samples/ApiDemos/res/layout/incoming_message_info.xml
new file mode 100644
index 0000000..723a4da
--- /dev/null
+++ b/samples/ApiDemos/res/layout/incoming_message_info.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+		<ImageView
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:src="@drawable/sample_thumb_2"
+            />
+
+        <TextView
+            android:id="@+id/message"
+            android:layout_gravity="center_vertical"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+            android:paddingLeft="6dip"
+            android:text="@string/incoming_message_info_message_text"
+            />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/incoming_message_panel.xml b/samples/ApiDemos/res/layout/incoming_message_panel.xml
new file mode 100644
index 0000000..3120e4e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/incoming_message_panel.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:background="@android:drawable/toast_frame">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/sample_thumb_2"
+                />
+
+            <TextView
+                android:id="@+id/message"
+                android:layout_gravity="center_vertical"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingLeft="6dip"
+                />
+
+    </LinearLayout>
+</FrameLayout>
diff --git a/samples/ApiDemos/res/layout/incoming_message_view.xml b/samples/ApiDemos/res/layout/incoming_message_view.xml
new file mode 100644
index 0000000..b286e6e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/incoming_message_view.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:paddingLeft="4dip"
+    android:paddingRight="4dip"
+    android:paddingTop="4dip"
+    >
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            >
+
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/sample_thumb_2"
+                    />
+
+                <TextView
+                    android:id="@+id/message"
+                    android:layout_gravity="center_vertical"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:paddingLeft="6dip"
+                    android:text="@string/incoming_message_view_message_text"
+                    />
+
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/message"
+            android:layout_gravity="center_vertical"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+            android:paddingTop="12dip"
+            android:text="@string/imcoming_message_view_message2_text"
+            />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/intents.xml b/samples/ApiDemos/res/layout/intents.xml
new file mode 100644
index 0000000..023e4e8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/intents.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates launching various intents.
+     See corresponding Java code com.example.android.apis.app.Intents.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/intents"/>
+
+    <Button android:id="@+id/get_music"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/get_music">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/launcher_shortcuts.xml b/samples/ApiDemos/res/layout/launcher_shortcuts.xml
new file mode 100644
index 0000000..c8fbb2a
--- /dev/null
+++ b/samples/ApiDemos/res/layout/launcher_shortcuts.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This activity provides information about launcher shortcuts -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    
+    <!--  Section: Information -->
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dip"
+        android:text="@string/msg_launcher_shortcuts" />
+    
+    <!--  Section: The intent that launched this Activity -->
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/label_intent" />
+    <TextView android:id="@+id/txt_shortcut_intent"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+ </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/layout_animation_1.xml b/samples/ApiDemos/res/layout/layout_animation_1.xml
new file mode 100644
index 0000000..2b25485
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animation_1.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/grid"
+    android:layoutAnimation="@anim/layout_grid_fade"
+
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:verticalSpacing="10dp"
+
+    android:horizontalSpacing="10dp"
+    android:numColumns="auto_fit"
+    android:columnWidth="60dp"
+    android:stretchMode="columnWidth"
+
+    android:gravity="center" />
diff --git a/samples/ApiDemos/res/layout/layout_animation_3.xml b/samples/ApiDemos/res/layout/layout_animation_3.xml
new file mode 100644
index 0000000..051fa8e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animation_3.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/list"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:layoutAnimation="@anim/layout_bottom_to_top_slide" />
diff --git a/samples/ApiDemos/res/layout/layout_animation_4.xml b/samples/ApiDemos/res/layout/layout_animation_4.xml
new file mode 100644
index 0000000..73b99b0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animation_4.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/grid"
+    android:layoutAnimation="@anim/layout_random_fade"
+
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:verticalSpacing="10dp"
+
+    android:horizontalSpacing="10dp"
+    android:numColumns="auto_fit"
+    android:columnWidth="60dp"
+    android:stretchMode="columnWidth"
+
+    android:gravity="center" />
diff --git a/samples/ApiDemos/res/layout/layout_animation_5.xml b/samples/ApiDemos/res/layout/layout_animation_5.xml
new file mode 100644
index 0000000..602fb18
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animation_5.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/grid"
+    android:layoutAnimation="@anim/layout_grid_inverse_fade"
+
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:verticalSpacing="10dp"
+
+    android:horizontalSpacing="10dp"
+    android:numColumns="auto_fit"
+    android:columnWidth="60dp"
+    android:stretchMode="columnWidth"
+
+    android:gravity="center" />
diff --git a/samples/ApiDemos/res/layout/layout_animation_6.xml b/samples/ApiDemos/res/layout/layout_animation_6.xml
new file mode 100644
index 0000000..026797e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animation_6.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/grid"
+    android:layoutAnimation="@anim/layout_wave_scale"
+
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:verticalSpacing="10dp"
+
+    android:horizontalSpacing="10dp"
+    android:numColumns="auto_fit"
+    android:columnWidth="60dp"
+    android:stretchMode="columnWidth"
+
+    android:gravity="center" />
diff --git a/samples/ApiDemos/res/layout/layout_animation_7.xml b/samples/ApiDemos/res/layout/layout_animation_7.xml
new file mode 100644
index 0000000..38260c7
--- /dev/null
+++ b/samples/ApiDemos/res/layout/layout_animation_7.xml
@@ -0,0 +1,57 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layoutAnimation="@anim/layout_animation_table"
+    android:animationCache="false"
+    android:clipToPadding="false"
+    android:padding="12dp"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:stretchColumns="1">
+
+    <TableRow
+        android:layoutAnimation="@anim/layout_animation_row_right_slide">
+        <TextView
+            android:gravity="right"
+            android:text="@string/layout_animation_name" />
+        <EditText />
+    </TableRow>
+
+    <TableRow
+        android:layoutAnimation="@anim/layout_animation_row_left_slide">
+        <TextView
+            android:gravity="right"
+            android:text="@string/layout_animation_lastname" />
+        <EditText />
+    </TableRow>
+
+    <TableRow
+        android:layoutAnimation="@anim/layout_animation_row_right_slide">
+        <TextView
+            android:gravity="right"
+            android:text="@string/layout_animation_phone" />
+        <EditText />
+    </TableRow>
+
+    <TableRow
+        android:layoutAnimation="@anim/layout_animation_row_left_slide">
+        <TextView
+            android:gravity="right"
+            android:text="@string/layout_animation_address" />
+        <EditText android:lines="3" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_1.xml b/samples/ApiDemos/res/layout/linear_layout_1.xml
new file mode 100644
index 0000000..ef01ced
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_1.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates a simple linear layout. The height of the layout is the sum of its children. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:background="@drawable/blue"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <!-- view1 goes on top -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_1_top"/>
+
+    <!-- view2 goes in the middle -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_1_middle"/>
+
+    <!-- view3 goes on the bottom -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_1_bottom"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_10.xml b/samples/ApiDemos/res/layout/linear_layout_10.xml
new file mode 100644
index 0000000..eb793fd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_10.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using a LinearLayout background to group related
+     TextViews, EditTexts, and Buttons. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <!-- Top label/button text field. -->
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:addStatesFromChildren="true"
+        android:gravity="center_vertical"
+        android:paddingRight="0dip"
+        android:background="@android:drawable/edit_text">
+
+        <!--
+            TextView label goes at the left.
+        -->
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/linear_layout_10_from"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="?android:attr/textAppearanceLargeInverse"
+        />
+
+        <!--
+            EditText goes in between.
+        -->
+        <EditText
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:singleLine="true"
+            android:background="@null"
+        />
+
+        <!--
+            The button goes at the right.
+        -->
+        <ImageButton
+            style="@android:style/Widget.Button.Inset"
+            android:src="@android:drawable/star_big_on"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="2dip"
+            android:layout_marginRight="2dip"
+            android:layout_marginBottom="2dip"
+            android:padding="10dip"
+        />
+
+    </LinearLayout>
+
+    <!-- Bottom label/button text field.  (Identical to the top one
+         except for the label.)  -->
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:addStatesFromChildren="true"
+        android:gravity="center_vertical"
+        android:paddingRight="0dip"
+        android:background="@android:drawable/edit_text">
+
+        <!--
+            TextView label goes at the left.
+        -->
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/linear_layout_10_to"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="?android:attr/textAppearanceLargeInverse"
+        />
+
+        <!--
+            EditText goes in between.
+        -->
+        <EditText
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:singleLine="true"
+            android:background="@null"
+        />
+
+        <!--
+            The button goes at the right.
+        -->
+        <ImageButton
+            style="@android:style/Widget.Button.Inset"
+            android:src="@android:drawable/star_big_on"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="2dip"
+            android:layout_marginRight="2dip"
+            android:layout_marginBottom="2dip"
+            android:padding="10dip"
+        />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_2.xml b/samples/ApiDemos/res/layout/linear_layout_2.xml
new file mode 100644
index 0000000..3cacccc
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_2.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates a simple linear layout. The layout fills the screen, with the children stacked from the top. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:background="@drawable/blue"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <!-- view1 goes on top -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_2_top"/>
+
+    <!-- view2 goes in the middle -->
+    <TextView
+       android:background="@drawable/box"
+       android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_2_middle"/>
+
+    <!-- view3 goes on the bottom -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_2_bottom"/>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/linear_layout_3.xml b/samples/ApiDemos/res/layout/linear_layout_3.xml
new file mode 100644
index 0000000..2b9b327
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_3.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates a simple linear layout. The layout fills the screen, with the
+    children stacked from the top. The middle child gets allocated any extra
+    space.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:background="@drawable/blue"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <!-- view1 goes on top -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_3_top"/>
+
+    <!-- view2 goes in the middle -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:text="@string/linear_layout_3_middle"/>
+
+    <!-- view3 goes on the bottom -->
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_3_bottom"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_4.xml b/samples/ApiDemos/res/layout/linear_layout_4.xml
new file mode 100644
index 0000000..139fb57
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_4.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates a horizontal linear layout with equally sized columns
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:background="@drawable/red"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"/>
+
+    <TextView
+        android:background="@drawable/green"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"/>
+
+    <TextView
+        android:background="@drawable/blue"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"/>
+
+    <TextView
+        android:background="@drawable/yellow"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_5.xml b/samples/ApiDemos/res/layout/linear_layout_5.xml
new file mode 100644
index 0000000..832a103
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_5.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates a nesting layouts to make a form
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:background="@drawable/blue"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:padding="10dip">
+
+    <!--
+        TextView goes on top...
+    -->
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_5_instructions"/>
+
+    <!--
+        Followed by the EditText field...
+
+        Also give it a standard background (the "android:"
+        part in @android:drawable/editbox_background
+        means it is system resource rather than
+        an application resource.
+    -->
+    <EditText
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:background="@android:drawable/editbox_background"/>
+
+    <!--
+        Use a horizontal layout to hold the two buttons.
+        This item has layout_gravity="right". This means the whole
+        horizontal LinearLayout is right aligned, not the individual
+        items within it. The horizontal LinearLayout's width is set to
+        wrap_content. (If it was fill_parent it would not have any
+        room to slide to the right.)
+    -->
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right" >
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/linear_layout_5_cancel"/>
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dip"
+            android:text="@string/linear_layout_5_ok" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_6.xml b/samples/ApiDemos/res/layout/linear_layout_6.xml
new file mode 100644
index 0000000..f4bb6a7
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_6.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+
+<!--
+    LinearLayout which uses a combination of wrap_content on itself and
+    fill_parent on its children to get every item to be the same width.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:background="@drawable/blue"
+    android:padding="20dip"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_6_one"/>
+
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_6_two"/>
+
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_6_three"/>
+
+    <TextView
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_6_four"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_7.xml b/samples/ApiDemos/res/layout/linear_layout_7.xml
new file mode 100644
index 0000000..19b22e5
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_7.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates a horizontal linear layout with equally sized columns.
+    Some columns force their height to match the parent.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:background="@drawable/red"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"
+        android:text="@string/linear_layout_7_small"/>
+
+    <TextView
+        android:background="@drawable/green"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"
+        android:text="@string/linear_layout_7_big"/>
+
+    <TextView
+        android:background="@drawable/blue"
+        android:layout_width="0dip"
+        android:layout_height="fill_parent"
+        android:layout_weight="1"
+        android:text="@string/linear_layout_7_small" />
+
+    <TextView
+        android:background="@drawable/yellow"
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:text="@string/linear_layout_7_wrap"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_8.xml b/samples/ApiDemos/res/layout/linear_layout_8.xml
new file mode 100644
index 0000000..f226043
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_8.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates a simple linear layout. The layout fills the screen, with the
+    children stacked from the top.
+    -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="30dip">
+  <LinearLayout
+      android:id="@+id/layout"
+      android:orientation="vertical"
+      android:background="@drawable/blue"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"
+      android:padding="30dip">
+
+    <TextView
+	android:background="@drawable/box"
+	android:layout_width="wrap_content"
+	android:layout_height="wrap_content"
+	android:text="@string/linear_layout_8_c"/>
+
+    <TextView
+	android:background="@drawable/box"
+	android:layout_width="wrap_content"
+	android:layout_height="wrap_content"
+	android:text="@string/linear_layout_8_b"/>
+
+    <TextView
+	android:background="@drawable/box"
+	android:layout_width="wrap_content"
+	android:layout_height="wrap_content"
+	android:text="@string/linear_layout_8_c"/>
+
+  </LinearLayout>
+
+</FrameLayout>
diff --git a/samples/ApiDemos/res/layout/linear_layout_9.xml b/samples/ApiDemos/res/layout/linear_layout_9.xml
new file mode 100644
index 0000000..eb91147
--- /dev/null
+++ b/samples/ApiDemos/res/layout/linear_layout_9.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates a simple linear layout. The layout fills the screen, with the
+    children stacked from the top.
+    -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <ListView android:id="@+id/list"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1.0" />
+
+    <Button
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/linear_layout_9_button" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/link.xml b/samples/ApiDemos/res/layout/link.xml
new file mode 100644
index 0000000..a65d000
--- /dev/null
+++ b/samples/ApiDemos/res/layout/link.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="wrap_content">
+
+  <!-- Four TextView widgets, each one displaying text containing links. -->
+
+  <!-- text1 automatically linkifies things like URLs and phone numbers. -->
+  <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:id="@+id/text1"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:autoLink="all"
+            android:text="@string/link_text_auto"
+            />
+
+  <!-- text2 uses a string resource containing explicit <a> tags to
+       specify links. -->
+  <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:id="@+id/text2"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:text="@string/link_text_manual"
+            />
+
+  <!-- text3 builds the text in the Java code using HTML. -->
+  <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:id="@+id/text3"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            />
+
+  <!-- text4 builds the text in the Java code without using HTML. -->
+  <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:id="@+id/text4"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/list_12.xml b/samples/ApiDemos/res/layout/list_12.xml
new file mode 100644
index 0000000..7f19b58
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_12.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent"
+    android:paddingLeft="8dip"
+    android:paddingRight="8dip">
+    
+    <ListView android:id="@android:id/list"
+        android:layout_width="fill_parent" 
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:stackFromBottom="true"
+        android:transcriptMode="normal"/>
+        
+    <EditText android:id="@+id/userText"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+        
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/list_13.xml b/samples/ApiDemos/res/layout/list_13.xml
new file mode 100644
index 0000000..681b46e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_13.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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">
+    
+    <ListView android:id="@android:id/list"
+        android:layout_width="fill_parent" 
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:drawSelectorOnTop="false"/>
+        
+    <TextView android:id="@+id/status"
+        android:layout_width="fill_parent" 
+        android:layout_height="wrap_content"
+        android:paddingLeft="8dip"
+        android:paddingRight="8dip"/>
+        
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/list_7.xml b/samples/ApiDemos/res/layout/list_7.xml
new file mode 100644
index 0000000..2dc7777
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_7.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical"
+	android:layout_width="fill_parent" 
+    android:layout_height="fill_parent"
+	android:paddingLeft="8dip"
+	android:paddingRight="8dip">
+	
+	<ListView android:id="@android:id/list"
+	    android:layout_width="fill_parent" 
+	    android:layout_height="0dip"
+	    android:layout_weight="1"
+	    android:drawSelectorOnTop="false"/>
+	    
+    <TextView android:id="@+id/phone"
+    	android:layout_width="fill_parent" 
+    	android:layout_height="wrap_content"
+    	android:background="@drawable/blue"/>
+    	
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/list_8.xml b/samples/ApiDemos/res/layout/list_8.xml
new file mode 100644
index 0000000..a88b67c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_8.xml
@@ -0,0 +1,61 @@
+<?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.
+-->
+
+<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:orientation="horizontal"
+        android:layout_width="fill_parent" 
+        android:layout_height="wrap_content">
+        
+        <Button android:id="@+id/add"
+            android:layout_width="wrap_content" 
+            android:layout_height="wrap_content"
+            android:text="@string/list_8_new_photo"/>
+            
+        <Button android:id="@+id/clear"
+            android:layout_width="wrap_content" 
+            android:layout_height="wrap_content"
+            android:text="@string/list_8_clear_photos"/>
+            
+    </LinearLayout>
+    
+    <!-- The frame layout is here since we will be showing either
+    the empty view or the list view.  -->
+    <FrameLayout
+        android:layout_width="fill_parent" 
+        android:layout_height="0dip"
+        android:layout_weight="1" >
+        <!-- Here is the list. Since we are using a ListActivity, we
+             have to call it "@android:id/list" so ListActivity will
+             find it -->
+        <ListView android:id="@android:id/list"
+            android:layout_width="fill_parent" 
+            android:layout_height="fill_parent"
+            android:drawSelectorOnTop="false"/>
+        
+        <!-- Here is the view to show if the list is emtpy -->
+        <TextView android:id="@+id/empty"
+            android:layout_width="fill_parent" 
+            android:layout_height="fill_parent"
+            android:text="@string/list_8_no_photos"/>
+            
+    </FrameLayout>
+        
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/list_item_checkbox.xml b/samples/ApiDemos/res/layout/list_item_checkbox.xml
new file mode 100644
index 0000000..fa1d2d8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_item_checkbox.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="fill_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:textAppearance="?android:attr/textAppearanceLarge"
+/>
diff --git a/samples/ApiDemos/res/layout/list_item_icon_text.xml b/samples/ApiDemos/res/layout/list_item_icon_text.xml
new file mode 100644
index 0000000..7206c04
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_item_icon_text.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <ImageView android:id="@+id/icon"
+        android:layout_width="48dip"
+        android:layout_height="48dip" />
+
+    <TextView android:id="@+id/text"
+        android:layout_gravity="center_vertical"
+        android:layout_width="0dip"
+        android:layout_weight="1.0"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/list_position.xml b/samples/ApiDemos/res/layout/list_position.xml
new file mode 100644
index 0000000..a82f6bc
--- /dev/null
+++ b/samples/ApiDemos/res/layout/list_position.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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:textSize="50sp"
+    android:textColor="#99FFFFFF"
+    android:background="#BB000000"
+    android:minWidth="70dip"
+    android:maxWidth="70dip"
+    android:padding="10dip"
+    android:gravity="center"
+/>
diff --git a/samples/ApiDemos/res/layout/local_sample.xml b/samples/ApiDemos/res/layout/local_sample.xml
new file mode 100644
index 0000000..e662921
--- /dev/null
+++ b/samples/ApiDemos/res/layout/local_sample.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<!-- Front-end for running application instrumentation demonstration.
+     See corresponding Java code com.android.sdk.app.LocalSample.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/local_sample"/>
+
+    <Button android:id="@+id/go"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/go">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/local_service_binding.xml b/samples/ApiDemos/res/layout/local_service_binding.xml
new file mode 100644
index 0000000..775b8fb
--- /dev/null
+++ b/samples/ApiDemos/res/layout/local_service_binding.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/local_service_binding"/>
+
+    <Button android:id="@+id/bind"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/bind_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/unbind"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/unbind_service">
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/local_service_controller.xml b/samples/ApiDemos/res/layout/local_service_controller.xml
new file mode 100644
index 0000000..7bb02ca
--- /dev/null
+++ b/samples/ApiDemos/res/layout/local_service_controller.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/local_service_controller"/>
+
+    <Button android:id="@+id/start"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/stop_service">
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/log_text_box_1.xml b/samples/ApiDemos/res/layout/log_text_box_1.xml
new file mode 100644
index 0000000..f06619d
--- /dev/null
+++ b/samples/ApiDemos/res/layout/log_text_box_1.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <Button
+        android:id="@+id/add"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/log_text_box_1_add_text"/>
+
+    <com.example.android.apis.text.LogTextBox
+        android:id="@+id/text"
+        android:background="@drawable/box"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:scrollbars="vertical"/>
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/log_text_box_1_do_nothing_text"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/mapview.xml b/samples/ApiDemos/res/layout/mapview.xml
new file mode 100644
index 0000000..97ef7ff
--- /dev/null
+++ b/samples/ApiDemos/res/layout/mapview.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates use of the com.google.android.maps.MapView.
+     See corresponding Java code com.example.android.apis.view.MapViewDemo.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main"
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent">
+    <com.google.android.maps.MapView
+        android:layout_width="fill_parent" 
+        android:layout_height="fill_parent"
+        android:enabled="true"
+        android:clickable="true"
+        android:apiKey="apisamples"
+        />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/marquee.xml b/samples/ApiDemos/res/layout/marquee.xml
new file mode 100644
index 0000000..6d40c84
--- /dev/null
+++ b/samples/ApiDemos/res/layout/marquee.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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">
+    
+    <Button
+        android:layout_width="150dip" 
+        android:layout_height="wrap_content"
+        android:text="@string/marquee_default"
+        android:singleLine="true"
+        android:ellipsize="marquee"/>
+        
+    <Button
+        android:layout_width="150dip" 
+        android:layout_height="wrap_content"
+        android:text="@string/marquee_once"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:marqueeRepeatLimit="1"/>
+        
+    <Button
+        android:layout_width="150dip" 
+        android:layout_height="wrap_content"
+        android:text="@string/marquee_forever"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:marqueeRepeatLimit="marquee_forever"/>  
+           
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/mediaplayer_1.xml b/samples/ApiDemos/res/layout/mediaplayer_1.xml
new file mode 100644
index 0000000..16ae61b
--- /dev/null
+++ b/samples/ApiDemos/res/layout/mediaplayer_1.xml
@@ -0,0 +1,31 @@
+<?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"
+    >
+    <Button android:id="@+id/localvideo"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent" 
+        android:text="@string/local_video" 
+    />
+    
+    <Button android:id="@+id/streamvideo"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent" 
+        android:text="@string/stream_video" 
+    />
+    
+    <Button android:id="@+id/localaudio"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent" 
+        android:text="@string/local_audio" 
+    />
+    
+    <Button android:id="@+id/resourcesaudio"
+        android:layout_height="wrap_content"
+        android:layout_width="fill_parent" 
+        android:text="@string/res_audio" 
+    />
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/mediaplayer_2.xml b/samples/ApiDemos/res/layout/mediaplayer_2.xml
new file mode 100644
index 0000000..e1e49dd
--- /dev/null
+++ b/samples/ApiDemos/res/layout/mediaplayer_2.xml
@@ -0,0 +1,13 @@
+<?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">
+
+    <SurfaceView android:id="@+id/surface"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center">
+    </SurfaceView>
+  
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/morse_code.xml b/samples/ApiDemos/res/layout/morse_code.xml
new file mode 100644
index 0000000..f536da2
--- /dev/null
+++ b/samples/ApiDemos/res/layout/morse_code.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This activity exercises search invocation options -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    
+    <EditText
+        android:id="@+id/text"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dip"
+        />
+    
+    <Button
+        android:id="@+id/button"
+        android:text="@string/vibrate"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/notify_with_text.xml b/samples/ApiDemos/res/layout/notify_with_text.xml
new file mode 100644
index 0000000..6cba90d
--- /dev/null
+++ b/samples/ApiDemos/res/layout/notify_with_text.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <Button
+        android:id="@+id/short_notify"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/notify_with_text_short_notify_text" />
+
+    <Button
+        android:id="@+id/long_notify"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/notify_with_text_long_notify_text" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/notifying_controller.xml b/samples/ApiDemos/res/layout/notifying_controller.xml
new file mode 100644
index 0000000..54cef17
--- /dev/null
+++ b/samples/ApiDemos/res/layout/notifying_controller.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/notifying_service_controller"/>
+
+    <Button android:id="@+id/notifyStart"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/notifyStop"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/stop_service">
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/preference_widget_mypreference.xml b/samples/ApiDemos/res/layout/preference_widget_mypreference.xml
new file mode 100644
index 0000000..20c0d56
--- /dev/null
+++ b/samples/ApiDemos/res/layout/preference_widget_mypreference.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- Custom preference type using a text view. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/mypreference_widget" 
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_vertical"
+    android:layout_marginRight="6sp"
+    android:focusable="false"
+    android:clickable="false" />
diff --git a/samples/ApiDemos/res/layout/progressbar_1.xml b/samples/ApiDemos/res/layout/progressbar_1.xml
new file mode 100644
index 0000000..0383de9
--- /dev/null
+++ b/samples/ApiDemos/res/layout/progressbar_1.xml
@@ -0,0 +1,74 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <ProgressBar android:id="@+id/progress_horizontal"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="200dip"
+        android:layout_height="wrap_content"
+        android:max="100"
+        android:progress="50"
+        android:secondaryProgress="75" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/progressbar_1_default_progress" />        
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <Button android:id="@+id/decrease"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/progressbar_1_minus" />
+
+        <Button android:id="@+id/increase"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/progressbar_1_plus" />
+
+    </LinearLayout>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/progressbar_1_secondary_progress" />        
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <Button android:id="@+id/decrease_secondary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/progressbar_1_minus" />
+
+        <Button android:id="@+id/increase_secondary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/progressbar_1_plus" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/progressbar_2.xml b/samples/ApiDemos/res/layout/progressbar_2.xml
new file mode 100644
index 0000000..2d43622
--- /dev/null
+++ b/samples/ApiDemos/res/layout/progressbar_2.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <ProgressBar android:id="@+android:id/progress_large"
+        style="?android:attr/progressBarStyleLarge"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <ProgressBar android:id="@+android:id/progress"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <ProgressBar android:id="@+android:id/progress_small"
+        style="?android:attr/progressBarStyleSmall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <ProgressBar android:id="@+android:id/progress_small_title"
+        style="?android:attr/progressBarStyleSmallTitle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/progressbar_3.xml b/samples/ApiDemos/res/layout/progressbar_3.xml
new file mode 100644
index 0000000..ac10a30
--- /dev/null
+++ b/samples/ApiDemos/res/layout/progressbar_3.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <Button android:id="@+id/showIndeterminate"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/progressbar_3_indeterminate" />
+
+    <Button android:id="@+id/showIndeterminateNoTitle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/progressbar_3_indeterminate_no_title" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/progressbar_4.xml b/samples/ApiDemos/res/layout/progressbar_4.xml
new file mode 100644
index 0000000..5e577a0
--- /dev/null
+++ b/samples/ApiDemos/res/layout/progressbar_4.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:orientation="vertical"
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content">
+
+    <Button android:id="@+id/toggle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/progressbar_4_toggle" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/radio_group_1.xml b/samples/ApiDemos/res/layout/radio_group_1.xml
new file mode 100644
index 0000000..3029207
--- /dev/null
+++ b/samples/ApiDemos/res/layout/radio_group_1.xml
@@ -0,0 +1,49 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    <RadioGroup
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:checkedButton="@+id/lunch"
+        android:id="@+id/menu">
+        <RadioButton
+            android:text="@string/radio_group_1_breakfast"
+            android:id="@+id/breakfast"
+            />
+        <RadioButton
+            android:text="@string/radio_group_1_lunch"
+            android:id="@id/lunch" />
+        <RadioButton
+            android:text="@string/radio_group_1_dinner"
+            android:id="@+id/dinner" />
+        <RadioButton
+            android:text="@string/radio_group_1_all"
+            android:id="@+id/all" />
+        <TextView
+            android:text="@string/radio_group_1_selection"
+            android:id="@+id/choice" />
+    </RadioGroup>
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/radio_group_1_clear"
+        android:id="@+id/clear" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/ratingbar_1.xml b/samples/ApiDemos/res/layout/ratingbar_1.xml
new file mode 100644
index 0000000..3256d3c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/ratingbar_1.xml
@@ -0,0 +1,60 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:paddingLeft="10dip"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <RatingBar android:id="@+id/ratingbar1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:numStars="3"
+        android:rating="2.5" />
+
+    <RatingBar android:id="@+id/ratingbar2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:numStars="5"
+        android:rating="2.25" />
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dip">
+        
+        <TextView android:id="@+id/rating"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+            
+        <RatingBar android:id="@+id/small_ratingbar"
+            style="?android:attr/ratingBarStyleSmall"
+            android:layout_marginLeft="5dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical" />
+            
+    </LinearLayout>
+
+    <RatingBar android:id="@+id/indicator_ratingbar"
+        style="?android:attr/ratingBarStyleIndicator"
+        android:layout_marginLeft="5dip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical" />
+            
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/read_asset.xml b/samples/ApiDemos/res/layout/read_asset.xml
new file mode 100644
index 0000000..79b8bb6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/read_asset.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates styled string resources.
+     See corresponding Java code com.android.sdk.content.StyledText -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <TextView android:id="@+id/text"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:textStyle="normal"/>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/receive_result.xml b/samples/ApiDemos/res/layout/receive_result.xml
new file mode 100644
index 0000000..461be6c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/receive_result.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates receiving activity results.
+    See corresponding Java code com.android.sdk.app.ReceiveResult.java.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/receive_result_instructions"/>
+
+    <TextView android:id="@+id/results"
+        android:layout_width="fill_parent" android:layout_height="10dip"
+        android:layout_weight="1"
+        android:paddingBottom="4dip"
+        android:background="@drawable/green">
+    </TextView>
+
+    <Button android:id="@+id/get"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:layout_weight="0"
+        android:text="@string/receive_result_result">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/redirect_enter.xml b/samples/ApiDemos/res/layout/redirect_enter.xml
new file mode 100644
index 0000000..f73d999
--- /dev/null
+++ b/samples/ApiDemos/res/layout/redirect_enter.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates redirection between activities.
+     See corresponding Java code com.android.sdk.app.RedirectEnter.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/redirect_enter"/>
+
+    <Button android:id="@+id/go"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/go">
+        <requestFocus />
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/redirect_getter.xml b/samples/ApiDemos/res/layout/redirect_getter.xml
new file mode 100644
index 0000000..9879b78
--- /dev/null
+++ b/samples/ApiDemos/res/layout/redirect_getter.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates redirection between activities.
+     See corresponding Java code com.android.sdk.app.RedirectEnter.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/redirect_getter"/>
+
+    <EditText android:id="@+id/text"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip">
+        <requestFocus />
+    </EditText>
+
+    <Button android:id="@+id/apply"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/apply" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/redirect_main.xml b/samples/ApiDemos/res/layout/redirect_main.xml
new file mode 100644
index 0000000..74de502
--- /dev/null
+++ b/samples/ApiDemos/res/layout/redirect_main.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates redirection between activities.
+     See corresponding Java code com.android.sdk.app.RedirectEnter.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/redirect_main"/>
+
+    <TextView android:id="@+id/text"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip" />
+
+    <Button android:id="@+id/clear"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/clear_text">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/newView"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/new_text">
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/relative_layout_1.xml b/samples/ApiDemos/res/layout/relative_layout_1.xml
new file mode 100644
index 0000000..122e718
--- /dev/null
+++ b/samples/ApiDemos/res/layout/relative_layout_1.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates stretching a view to fill the space between two other views
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <!-- view1 goes on top -->
+    <TextView
+        android:id="@+id/view1"
+        android:background="@drawable/red"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:text="@string/relative_layout_1_top"/>
+
+    <!-- view2 goes on the bottom -->
+    <TextView
+        android:id="@+id/view2"
+        android:background="@drawable/green"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:text="@string/relative_layout_1_bottom"/>
+
+    <!-- view3 stretches betweeen view1 and view2 -->
+    <TextView
+        android:id="@+id/view3"
+        android:background="@drawable/yellow"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_above="@id/view2"
+        android:layout_below="@id/view1"
+        android:text="@string/relative_layout_1_center"/>
+
+</RelativeLayout>
+
diff --git a/samples/ApiDemos/res/layout/relative_layout_2.xml b/samples/ApiDemos/res/layout/relative_layout_2.xml
new file mode 100644
index 0000000..dc613e6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/relative_layout_2.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using a relative layout to create a form -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/blue"
+    android:padding="10dip">
+
+    <!--
+        TextView goes at the top left by default .
+    -->
+    <TextView
+        android:id="@+id/label"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/relative_layout_2_instructions"/>
+
+    <!--
+        Put the EditText field under the TextView
+        Also give it a standard background (the "android:"
+        part in @android:drawable/editbox_background
+        means it is system resource rather than
+        an application resource.
+    -->
+    <EditText
+        android:id="@+id/entry"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:background="@android:drawable/editbox_background"
+        android:layout_below="@id/label"/>
+
+    <!--
+        The OK button goes below the EditText field.
+        It is also aligned to the right edge of the parent
+        (respecting the parent's padding).
+        The OK button comes first so the Cancel button
+        can be specified relative to the OK button.
+    -->
+    <Button
+        android:id="@+id/ok"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/entry"
+        android:layout_alignParentRight="true"
+        android:layout_marginLeft="10dip"
+        android:text="@string/relative_layout_2_ok" />
+
+    <!--
+        The Cancel button is aligned with the top of
+        the OK button and positioned to the left of it.
+        Since the OK button has a left margin of 10, there
+        is some space between the two buttons.
+    -->
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_toLeftOf="@id/ok"
+        android:layout_alignTop="@id/ok"
+        android:text="@string/relative_layout_2_cancel" />
+
+</RelativeLayout>
+
diff --git a/samples/ApiDemos/res/layout/remote_service_binding.xml b/samples/ApiDemos/res/layout/remote_service_binding.xml
new file mode 100644
index 0000000..a353efb
--- /dev/null
+++ b/samples/ApiDemos/res/layout/remote_service_binding.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/remote_service_binding"/>
+
+    <Button android:id="@+id/bind"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/bind_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/unbind"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/unbind_service">
+    </Button>
+
+    <Button android:id="@+id/kill"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/kill_process">
+    </Button>
+
+    <TextView android:id="@+id/callback"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:gravity="center_horizontal" android:paddingTop="4dip"/>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/remote_service_controller.xml b/samples/ApiDemos/res/layout/remote_service_controller.xml
new file mode 100644
index 0000000..48e4c95
--- /dev/null
+++ b/samples/ApiDemos/res/layout/remote_service_controller.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/remote_service_controller"/>
+
+    <Button android:id="@+id/start"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/stop_service">
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/reorder_four.xml b/samples/ApiDemos/res/layout/reorder_four.xml
new file mode 100644
index 0000000..45f13a3
--- /dev/null
+++ b/samples/ApiDemos/res/layout/reorder_four.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
+     See corresponding Java code com.example.android.apis.app.ReorderOnLaunch.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/reorder_four_text"/>
+
+    <Button android:id="@+id/reorder_second_to_front"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/reorder_second_to_front">
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/reorder_on_launch.xml b/samples/ApiDemos/res/layout/reorder_on_launch.xml
new file mode 100644
index 0000000..850a2f5
--- /dev/null
+++ b/samples/ApiDemos/res/layout/reorder_on_launch.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
+     See corresponding Java code com.android.sdk.app.ReorderOnLaunch.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/reorder_on_launch"/>
+
+    <Button android:id="@+id/reorder_launch_two"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/reorder_launch_two">
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/reorder_three.xml b/samples/ApiDemos/res/layout/reorder_three.xml
new file mode 100644
index 0000000..30ef41b
--- /dev/null
+++ b/samples/ApiDemos/res/layout/reorder_three.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
+     See corresponding Java code com.example.android.apis.app.ReorderOnLaunch.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/reorder_three_text"/>
+
+    <Button android:id="@+id/reorder_launch_four"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/reorder_launch_four">
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/reorder_two.xml b/samples/ApiDemos/res/layout/reorder_two.xml
new file mode 100644
index 0000000..7132561
--- /dev/null
+++ b/samples/ApiDemos/res/layout/reorder_two.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates using Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
+     See corresponding Java code com.example.android.apis.app.ReorderOnLaunch.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/reorder_two_text"/>
+
+    <Button android:id="@+id/reorder_launch_three"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/reorder_launch_three">
+    </Button>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/resources.xml b/samples/ApiDemos/res/layout/resources.xml
new file mode 100644
index 0000000..60ec581
--- /dev/null
+++ b/samples/ApiDemos/res/layout/resources.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+    Demonstrates resources.
+
+    See corresponding Java code:
+    com.example.android.apis.content.ResourcesSample
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/styled_text"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:textStyle="normal"
+        />
+
+    <TextView
+        android:id="@+id/plain_text"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:textStyle="normal"
+        />
+
+    <TextView
+        android:id="@+id/res1"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:textStyle="normal"
+        />
+
+</LinearLayout>
+
+
diff --git a/samples/ApiDemos/res/layout/save_restore_state.xml b/samples/ApiDemos/res/layout/save_restore_state.xml
new file mode 100644
index 0000000..4f3f8ee
--- /dev/null
+++ b/samples/ApiDemos/res/layout/save_restore_state.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates saving and restoring activity state.
+     See corresponding Java code com.android.sdk.app.SaveRestoreState.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView android:id="@+id/msg"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip" />
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/saves_state"/>
+
+    <EditText android:id="@+id/saved"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:background="@drawable/green"
+        android:text="@string/initial_text"
+        android:freezesText="true">
+        <requestFocus />
+    </EditText>
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingTop="8dip"
+        android:paddingBottom="4dip"
+        android:text="@string/no_saves_state"/>
+
+    <EditText 
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:background="@drawable/red"
+        android:text="@string/initial_text">
+    </EditText>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/scroll_view_1.xml b/samples/ApiDemos/res/layout/scroll_view_1.xml
new file mode 100644
index 0000000..0552807
--- /dev/null
+++ b/samples/ApiDemos/res/layout/scroll_view_1.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:scrollbars="none">
+
+    <LinearLayout
+        android:id="@+id/layout"
+        android:orientation="vertical"
+        android:layout_width="fill_parent" android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_text_1"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_button_1"/>
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_text_2"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_button_2"/>
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_text_3"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_button_3"/>
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_text_4"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_button_4"/>
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_text_5"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_button_5"/>
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_text_6"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_1_button_6"/>
+
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/scroll_view_2.xml b/samples/ApiDemos/res/layout/scroll_view_2.xml
new file mode 100644
index 0000000..0107e46
--- /dev/null
+++ b/samples/ApiDemos/res/layout/scroll_view_2.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:scrollbars="none">
+
+    <LinearLayout
+        android:id="@+id/layout"
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_2_text_1"/>
+
+        <Button
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scroll_view_2_button_1"/>
+
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/scrollbar1.xml b/samples/ApiDemos/res/layout/scrollbar1.xml
new file mode 100644
index 0000000..7221b3e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/scrollbar1.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_1_text"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/scrollbar2.xml b/samples/ApiDemos/res/layout/scrollbar2.xml
new file mode 100644
index 0000000..4882a72
--- /dev/null
+++ b/samples/ApiDemos/res/layout/scrollbar2.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:scrollbarTrackVertical="@drawable/scrollbar_vertical_track"
+    android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb"
+    android:scrollbarSize="12dip">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/scrollbar_2_text"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/scrollbar3.xml b/samples/ApiDemos/res/layout/scrollbar3.xml
new file mode 100644
index 0000000..c272e45
--- /dev/null
+++ b/samples/ApiDemos/res/layout/scrollbar3.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <ScrollView
+            android:layout_width="100dip"
+            android:layout_height="120dip"
+            android:background="#FF0000">
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent">
+
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+                <TextView
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/scrollbar_2_text" />
+            </LinearLayout>
+        </ScrollView>
+
+        <ScrollView
+            android:layout_width="100dip"
+            android:layout_height="120dip"
+            android:background="#00FF00"
+            android:paddingRight="12dip">
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/scrollbar_3_text"
+                android:textColor="#000000"
+                android:background="#60AA60" />
+        </ScrollView>
+
+        <ScrollView
+            android:id="@+id/view3"
+            android:layout_width="100dip"
+            android:layout_height="120dip"
+            android:background="@android:drawable/edit_text">
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:textColor="#000000"
+                android:text="@string/scrollbar_3_text" />
+        </ScrollView>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+        <ScrollView
+            android:id="@+id/view4"
+            android:layout_width="100dip"
+            android:layout_height="120dip"
+            android:scrollbarStyle="outsideOverlay"
+            android:background="@android:drawable/edit_text">
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:textColor="#000000"
+                android:text="@string/scrollbar_3_text" />
+        </ScrollView>
+        <ScrollView
+            android:id="@+id/view5"
+            android:layout_width="100dip"
+            android:layout_height="120dip"
+            android:scrollbarStyle="outsideInset"
+            android:background="@android:drawable/edit_text">
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:textColor="#000000"
+                android:text="@string/scrollbar_3_text" />
+        </ScrollView>
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/search_invoke.xml b/samples/ApiDemos/res/layout/search_invoke.xml
new file mode 100644
index 0000000..b78a616
--- /dev/null
+++ b/samples/ApiDemos/res/layout/search_invoke.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This activity exercises search invocation options -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    
+    <!--  Section: Information -->
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dip"
+        android:text="@string/msg_search" />
+    
+     <!--  Section: Invocation -->
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/search_sect_invocation" />
+
+    <Button android:id="@+id/btn_start_search"
+        android:text="@string/label_onsearchrequested"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+            
+    <Spinner android:id="@+id/spinner_menu_mode"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:drawSelectorOnTop="true" />
+            
+    <!--  Section: Options -->
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/search_sect_options" />
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/label_search_query_prefill" />
+            <EditText android:id="@+id/txt_query_prefill"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:maxEms="10"
+                android:minEms="10" />
+        </LinearLayout>
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/label_search_query_appdata" />
+            <EditText android:id="@+id/txt_query_appdata"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:maxEms="10"
+                android:minEms="10" />
+        </LinearLayout>
+    </LinearLayout>
+     
+     
+ </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/search_query_results.xml b/samples/ApiDemos/res/layout/search_query_results.xml
new file mode 100644
index 0000000..03f1ae6
--- /dev/null
+++ b/samples/ApiDemos/res/layout/search_query_results.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This activity displays search queries and "results" -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    
+    <!--  Section: Information -->
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dip"
+        android:text="@string/msg_search_results" />
+    
+    <!--  Section: Search Query String -->
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/label_search_query" />
+        <TextView android:id="@+id/txt_query"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <!--  Section: Search Query application context data -->
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/label_search_appdata" />
+        <TextView android:id="@+id/txt_appdata"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <!--  Section: How the query was delivered -->
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/label_search_deliveredby" />
+        <TextView android:id="@+id/txt_deliveredby"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+ </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/seekbar_1.xml b/samples/ApiDemos/res/layout/seekbar_1.xml
new file mode 100644
index 0000000..513114e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/seekbar_1.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <SeekBar android:id="@+id/seek"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:max="100"
+        android:progress="50"
+        android:secondaryProgress="75" />
+
+    <TextView android:id="@+id/progress"
+       	android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+    <TextView android:id="@+id/tracking"
+       	android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/select_dialog.xml b/samples/ApiDemos/res/layout/select_dialog.xml
new file mode 100644
index 0000000..ad826af
--- /dev/null
+++ b/samples/ApiDemos/res/layout/select_dialog.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates different uses of the android.app.SelectDialog.
+     See corresponding Java code com.android.sdk.app.SelectDialogSamples.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:orientation="vertical">
+    <Button android:id="@+id/show_dialog"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:text="@string/select_dialog_show"/>
+    <TextView android:id="@+id/message"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"/>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/send_result.xml b/samples/ApiDemos/res/layout/send_result.xml
new file mode 100644
index 0000000..386c3fc
--- /dev/null
+++ b/samples/ApiDemos/res/layout/send_result.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates receiving activity results.
+     See corresponding Java code com.android.sdk.app.ReceiveResult.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="8dip"
+        android:text="@string/pick_result"/>
+
+    <Button android:id="@+id/corky"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/corky">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/violet"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/violet">
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/service_start_arguments_controller.xml b/samples/ApiDemos/res/layout/service_start_arguments_controller.xml
new file mode 100644
index 0000000..f10a2c3
--- /dev/null
+++ b/samples/ApiDemos/res/layout/service_start_arguments_controller.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.ServiceStartArguments.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="fill_parent" android:layout_height="fill_parent">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/service_start_arguments_controller"/>
+
+    <Button android:id="@+id/start1"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start1_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/start2"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start2_service">
+    </Button>
+
+    <Button android:id="@+id/start3"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/start3_service">
+    </Button>
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/shape_drawable_1.xml b/samples/ApiDemos/res/layout/shape_drawable_1.xml
new file mode 100644
index 0000000..037e844
--- /dev/null
+++ b/samples/ApiDemos/res/layout/shape_drawable_1.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
+	android:layout_width="fill_parent"
+	android:layout_height="wrap_content">
+	
+    <LinearLayout
+    	android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+        
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="50dip"
+			android:src="@drawable/shape_1" />
+			
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:src="@drawable/line" />
+			
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="50dip"
+			android:src="@drawable/shape_2" />
+			
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:src="@drawable/line" />
+			
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="50dip"
+			android:src="@drawable/shape_3" />
+			
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:src="@drawable/line" />
+					
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="50dip"
+			android:src="@drawable/shape_4" />
+			
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:src="@drawable/line" />
+							
+		<ImageView
+			android:layout_width="fill_parent"
+			android:layout_height="50dip"
+			android:src="@drawable/shape_5" />
+	</LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/spinner_1.xml b/samples/ApiDemos/res/layout/spinner_1.xml
new file mode 100644
index 0000000..3d5f3c1
--- /dev/null
+++ b/samples/ApiDemos/res/layout/spinner_1.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="10dip"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/spinner_1_color"
+    />
+
+    <Spinner android:id="@+id/spinner1"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:drawSelectorOnTop="true"
+        android:prompt="@string/spinner_1_color_prompt"
+    />
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dip"
+        android:text="@string/spinner_1_planet"
+    />
+
+    <Spinner android:id="@+id/spinner2"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:drawSelectorOnTop="true"
+        android:prompt="@string/spinner_1_planet_prompt"
+    />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/layout/status_bar_balloon.xml b/samples/ApiDemos/res/layout/status_bar_balloon.xml
new file mode 100644
index 0000000..58f1bbb
--- /dev/null
+++ b/samples/ApiDemos/res/layout/status_bar_balloon.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:baselineAligned="false"
+    android:gravity="center_vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+   <ImageView android:id="@+id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="10dip" />
+    <TextView android:id="@+id/text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="#ffffffff" />    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/status_bar_notifications.xml b/samples/ApiDemos/res/layout/status_bar_notifications.xml
new file mode 100644
index 0000000..11f3c96
--- /dev/null
+++ b/samples/ApiDemos/res/layout/status_bar_notifications.xml
@@ -0,0 +1,157 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+    
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/status_bar_notifications_icons_only" />
+            
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+        
+            <Button
+                android:id="@+id/happy"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_happy" />
+        
+            <Button
+                android:id="@+id/neutral"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_ok" />
+                
+              <Button
+                android:id="@+id/sad"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_sad" />
+                
+        </LinearLayout>
+        
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dip"
+            android:text="@string/status_bar_notifications_icons_and_marquee" />
+            
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+        
+            <Button
+                android:id="@+id/happyMarquee"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_happy" />
+        
+            <Button
+                android:id="@+id/neutralMarquee"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_ok" />
+                
+              <Button
+                android:id="@+id/sadMarquee"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_sad" />
+                
+        </LinearLayout>
+        
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dip"
+            android:text="@string/status_bar_notifications_remote_views" />
+            
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+        
+            <Button
+                android:id="@+id/happyViews"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_happy" />
+        
+            <Button
+                android:id="@+id/neutralViews"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_ok" />
+                
+              <Button
+                android:id="@+id/sadViews"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_sad" />
+                
+        </LinearLayout>
+    
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dip"
+            android:text="@string/status_bar_notifications_defaults" />
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+        
+            <Button
+                android:id="@+id/defaultSound"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_default_sound" />
+        
+            <Button
+                android:id="@+id/defaultVibrate"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_default_vibrate" />
+                
+              <Button
+                android:id="@+id/defaultAll"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/status_bar_notifications_default_all" />
+                
+        </LinearLayout>
+    
+        <Button android:id="@+id/clear"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dip"
+            android:text="@string/status_bar_notifications_clear" />
+            
+    </LinearLayout>
+
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/styled_text.xml b/samples/ApiDemos/res/layout/styled_text.xml
new file mode 100644
index 0000000..610ea64
--- /dev/null
+++ b/samples/ApiDemos/res/layout/styled_text.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates styled string resources.
+     See corresponding Java code com.android.sdk.content.StyledText -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:text="@string/styled_text_rsrc"/>
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:textStyle="normal"
+        android:text="@string/styled_text"/>
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        />
+
+    <TextView
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:text="@string/styled_text_prog"/>
+
+    <TextView android:id="@+id/text"
+        android:layout_width="fill_parent" android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:textStyle="normal"/>
+
+</LinearLayout>
+
+
diff --git a/samples/ApiDemos/res/layout/surface_view_overlay.xml b/samples/ApiDemos/res/layout/surface_view_overlay.xml
new file mode 100644
index 0000000..a557e22
--- /dev/null
+++ b/samples/ApiDemos/res/layout/surface_view_overlay.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates changing view visibility. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+
+    <!-- Here is where we put the SurfaceView, in a frame so that we can
+         stack other views on top of it. -->
+    <FrameLayout
+            android:layout_width="fill_parent"
+            android:layout_height="0px"
+            android:layout_weight="1">
+
+        <android.opengl.GLSurfaceView android:id="@+id/glsurfaceview"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent" />
+
+        <LinearLayout android:id="@+id/hidecontainer"
+                android:orientation="vertical"
+                android:visibility="gone"
+                android:background="@drawable/translucent_background"
+                android:gravity="center"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent">
+
+            <Button android:id="@+id/hideme1"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:visibility="gone"
+                    android:text="@string/hide_me"/>
+            
+            <Button android:id="@+id/hideme2"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:visibility="gone"
+                    android:text="@string/hide_me"/>
+                    
+        </LinearLayout>
+        
+    </FrameLayout>
+            
+    <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center">
+
+        <Button android:id="@+id/vis"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/visibility_1_vis"/>
+
+        <Button android:id="@+id/invis"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/visibility_1_invis"/>
+
+        <Button android:id="@+id/gone"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/visibility_1_gone"/>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_1.xml b/samples/ApiDemos/res/layout/table_layout_1.xml
new file mode 100644
index 0000000..8d95e82
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_1.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TableRow>
+        <TextView
+          android:text="@string/table_layout_1_star"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_1_open"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_1_open_shortcut"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_1_triple_star"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_1_save"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_1_save_shortcut"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_1_star"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_1_quit"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_1_quit_shortcut"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_10.xml b/samples/ApiDemos/res/layout/table_layout_10.xml
new file mode 100644
index 0000000..6c558e7
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_10.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+   android:layout_width="fill_parent"
+   android:layout_height="fill_parent"
+   android:stretchColumns="1">
+
+   <TableRow>
+       <TextView
+           android:text="@string/table_layout_10_user"
+           android:textStyle="bold"
+           android:gravity="right"
+           android:padding="3dip" />
+
+       <EditText android:id="@+id/username"
+           android:text="@string/table_layout_10_username_text"
+           android:padding="3dip"
+           android:scrollHorizontally="true" />
+   </TableRow>
+
+   <TableRow>
+       <TextView
+           android:text="@string/table_layout_10_password"
+           android:textStyle="bold"
+           android:gravity="right"
+           android:padding="3dip" />
+
+       <EditText android:id="@+id/password"
+           android:text="@string/table_layout_10_password_text"
+           android:password="true"
+           android:padding="3dip"
+           android:scrollHorizontally="true" />
+   </TableRow>
+
+   <TableRow
+       android:gravity="right">
+
+       <Button android:id="@+id/cancel"
+           android:text="@string/table_layout_10_cancel" />
+
+       <Button android:id="@+id/login"
+           android:text="@string/table_layout_10_login" />
+   </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_11.xml b/samples/ApiDemos/res/layout/table_layout_11.xml
new file mode 100644
index 0000000..e40e28a
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_11.xml
@@ -0,0 +1,93 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:stretchColumns="1">
+
+    <TableRow>
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_7_open"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_7_open_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_7_save"
+            android:background="#FF00FF00"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_7_save_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <!-- Horizontally centers the content of the cell -->
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_7_save_as"
+            android:background="#FFFF0000"
+            android:layout_gravity="center_horizontal"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_7_save_as_shortcut"
+            android:background="#FFFF00FF"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <View
+        android:layout_height="2dip"
+        android:background="#FF909090" />
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_7_x"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_7_import"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <View
+            android:layout_height="68dip"
+            android:background="#FF909090" />
+        <!-- Aligns the content of the cell to the bottom right -->
+        <TextView
+            android:text="@string/table_layout_7_export"
+            android:background="#FFFF0000"
+            android:layout_gravity="right|bottom"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_7_export_shortcut"
+            android:background="#FF00FFFF"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <View
+        android:layout_height="2dip"
+        android:background="#FF909090" />
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_12.xml b/samples/ApiDemos/res/layout/table_layout_12.xml
new file mode 100644
index 0000000..423e34e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_12.xml
@@ -0,0 +1,85 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_12_a"
+            android:background="#FFFF0000"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_12_b"
+            android:background="#FF00FF00"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_12_c"
+            android:background="#FF0000FF"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_12_d"
+            android:layout_span="2"
+            android:gravity="center_horizontal"
+            android:background="#FF0000FF"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_12_e"
+            android:background="#FF00FF00"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_12_f"
+            android:background="#FFFF00FF"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_12_g"
+            android:background="#FF00FF00"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_12_h"
+            android:background="#FFFF0000"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_12_a"
+            android:background="#FF00FF00"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_12_b"
+            android:layout_span="2"
+            android:gravity="center_horizontal"
+            android:background="#FF0000FF"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_12_g"
+            android:layout_span="3"
+            android:gravity="center_horizontal"
+            android:background="#FFC0C0C0"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_2.xml b/samples/ApiDemos/res/layout/table_layout_2.xml
new file mode 100644
index 0000000..c5134d3
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_2.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TableRow>
+        <Button
+            android:text="@string/table_layout_2_open" />
+        <TextView
+            android:text="@string/table_layout_2_path_1"
+            android:padding="3dip" />
+    </TableRow>
+    <TableRow>
+        <Button
+            android:text="@string/table_layout_2_save_all"/>
+    </TableRow>
+    <TableRow>
+        <Button
+            android:text="@string/table_layout_2_save"
+            android:visibility="invisible" />
+        <TextView
+            android:text="@string/table_layout_2_path_2"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_3.xml b/samples/ApiDemos/res/layout/table_layout_3.xml
new file mode 100644
index 0000000..44415fc
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_3.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:shrinkColumns="2, 3">
+
+    <!-- Rows have different number of columns and content doesn't fit on
+         screen: column 4 of row 2 shrinks all of the other columns -->
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_3_star"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_open"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_open_shortcut"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_3_triple_star"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_save"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_save_shortcut"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_too_long"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_3_star"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_quit"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_3_quit_shortcut"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_4.xml b/samples/ApiDemos/res/layout/table_layout_4.xml
new file mode 100644
index 0000000..a9b7b42
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_4.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<!-- Stretch some columns -->
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:stretchColumns="1">
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_4_open"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_4_open_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_4_save"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_4_save_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_5.xml b/samples/ApiDemos/res/layout/table_layout_5.xml
new file mode 100644
index 0000000..773d729
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_5.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Stretch some columns -->
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:stretchColumns="1">
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_5_open"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_5_open_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_5_save"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_5_save_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_5_save_as"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_5_save_as_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <View
+        android:layout_height="2dip"
+        android:background="#FF909090" />
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_5_import"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_5_export"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_5_export_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <View
+        android:layout_height="2dip"
+        android:background="#FF909090" />
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_5_quit"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_6.xml b/samples/ApiDemos/res/layout/table_layout_6.xml
new file mode 100644
index 0000000..9607f1c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_6.xml
@@ -0,0 +1,92 @@
+<?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.
+-->
+
+<!-- Stretch some columns -->
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:stretchColumns="1">
+
+    <TableRow>
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_6_open"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_6_open_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_6_save"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_6_save_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_6_save_as"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_6_save_as_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <View
+        android:layout_height="2dip"
+        android:background="#FF909090" />
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_6_x"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_6_import"
+            android:padding="3dip" />
+    </TableRow>
+
+    <TableRow>
+        <TextView
+            android:text="@string/table_layout_6_x"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_6_export"
+            android:padding="3dip" />
+        <TextView
+            android:text="@string/table_layout_6_export_shortcut"
+            android:gravity="right"
+            android:padding="3dip" />
+    </TableRow>
+
+    <View
+        android:layout_height="2dip"
+        android:background="#FF909090" />
+
+    <TableRow>
+        <TextView
+            android:layout_column="1"
+            android:text="@string/table_layout_6_quit"
+            android:padding="3dip" />
+    </TableRow>
+</TableLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_7.xml b/samples/ApiDemos/res/layout/table_layout_7.xml
new file mode 100644
index 0000000..88c4910
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_7.xml
@@ -0,0 +1,106 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <TableLayout
+        android:id="@+id/menu"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:stretchColumns="1"
+        android:collapseColumns="2">
+
+        <TableRow>
+            <TextView
+                android:layout_column="1"
+                android:text="@string/table_layout_7_open"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_7_open_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:layout_column="1"
+                android:text="@string/table_layout_7_save"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_7_save_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:layout_column="1"
+                android:text="@string/table_layout_7_save_as"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_7_save_as_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <View
+            android:layout_height="2dip"
+            android:background="#FF909090" />
+
+        <TableRow>
+            <TextView
+                android:text="@string/table_layout_7_x"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_7_import"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:text="@string/table_layout_7_x"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_7_export"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_7_export_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <View
+            android:layout_height="2dip"
+            android:background="#FF909090" />
+    </TableLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <Button
+            android:id="@+id/toggle2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/table_layout_7_toggle_checkmarks" />
+        <Button
+            android:id="@+id/toggle1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/table_layout_7_toggle_shortcuts" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_8.xml b/samples/ApiDemos/res/layout/table_layout_8.xml
new file mode 100644
index 0000000..a63a8e8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_8.xml
@@ -0,0 +1,87 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <TableLayout
+        android:id="@+id/menu"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <TableRow>
+            <TextView
+                android:layout_column="1"
+                android:text="@string/table_layout_8_open"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_8_open_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:layout_column="1"
+                android:text="@string/table_layout_8_save"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_8_save_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:layout_column="1"
+                android:text="@string/table_layout_8_save_as"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_8_save_as_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:text="@string/table_layout_8_x"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_8_import"
+                android:padding="3dip" />
+        </TableRow>
+
+        <TableRow>
+            <TextView
+                android:text="@string/table_layout_8_x"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_8_export"
+                android:padding="3dip" />
+            <TextView
+                android:text="@string/table_layout_8_export_shortcut"
+                android:gravity="right"
+                android:padding="3dip" />
+        </TableRow>
+    </TableLayout>
+
+    <Button
+        android:id="@+id/toggle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/table_layout_8_toggle_stretch" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/table_layout_9.xml b/samples/ApiDemos/res/layout/table_layout_9.xml
new file mode 100644
index 0000000..a2d6564
--- /dev/null
+++ b/samples/ApiDemos/res/layout/table_layout_9.xml
@@ -0,0 +1,92 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+        <TableLayout
+            android:id="@+id/menu"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <TableRow>
+                <TextView
+                    android:text="@string/table_layout_9_open"
+                    android:padding="3dip" />
+                <TextView
+                    android:text="@string/table_layout_9_open_shortcut"
+                    android:gravity="right"
+                    android:padding="3dip" />
+            </TableRow>
+
+            <TableRow>
+                <TextView
+                    android:text="@string/table_layout_9_save"
+                    android:padding="3dip" />
+                <TextView
+                    android:text="@string/table_layout_9_save_shortcut"
+                    android:gravity="right"
+                    android:padding="3dip" />
+            </TableRow>
+
+            <TableRow>
+                <TextView
+                    android:text="@string/table_layout_9_save_as"
+                    android:padding="3dip" />
+                <TextView
+                    android:text="@string/table_layout_9_save_as_shortcut"
+                    android:gravity="right"
+                    android:padding="3dip" />
+            </TableRow>
+
+            <TableRow>
+                <TextView
+                    android:text="@string/table_layout_9_save_all"
+                    android:padding="3dip" />
+                <TextView
+                    android:text="@string/table_layout_9_save_all_shortcut"
+                    android:gravity="right"
+                    android:padding="3dip" />
+            </TableRow>
+
+            <TableRow>
+                <TextView
+                    android:text="@string/table_layout_9_import"
+                    android:padding="3dip" />
+            </TableRow>
+
+            <TableRow>
+                <TextView
+                    android:text="@string/table_layout_9_export"
+                    android:padding="3dip" />
+                <TextView
+                    android:text="@string/table_layout_9_export_shortcut"
+                    android:gravity="right"
+                    android:padding="3dip" />
+            </TableRow>
+        </TableLayout>
+
+        <Button
+            android:id="@+id/toggle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/table_layout_9_toggle_shrink" />
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/tabs1.xml b/samples/ApiDemos/res/layout/tabs1.xml
new file mode 100644
index 0000000..5a17693
--- /dev/null
+++ b/samples/ApiDemos/res/layout/tabs1.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <TextView android:id="@+id/view1"
+        android:background="@drawable/blue"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:text="@string/tabs_1_tab_1"/>
+
+    <TextView android:id="@+id/view2"
+        android:background="@drawable/red"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:text="@string/tabs_1_tab_2"/>
+
+    <TextView android:id="@+id/view3"
+        android:background="@drawable/green"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:text="@string/tabs_1_tab_3"/>
+
+</FrameLayout>
diff --git a/samples/ApiDemos/res/layout/text_switcher_1.xml b/samples/ApiDemos/res/layout/text_switcher_1.xml
new file mode 100644
index 0000000..d7be743
--- /dev/null
+++ b/samples/ApiDemos/res/layout/text_switcher_1.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <Button android:id="@+id/next"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/text_switcher_1_next_text" />
+
+    <TextSwitcher android:id="@+id/switcher"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/translucent_background.xml b/samples/ApiDemos/res/layout/translucent_background.xml
new file mode 100644
index 0000000..6b6e1cf
--- /dev/null
+++ b/samples/ApiDemos/res/layout/translucent_background.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates an activity with a fancy translucent background.
+     See corresponding Java code com.android.sdk.app.TranslucentBackground.java. -->
+
+<!-- This screen consists of a single text field that displays some text. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:gravity="center_vertical|center_horizontal"
+    android:text="@string/translucent_background"/>
diff --git a/samples/ApiDemos/res/layout/videoview.xml b/samples/ApiDemos/res/layout/videoview.xml
new file mode 100644
index 0000000..4f35ace
--- /dev/null
+++ b/samples/ApiDemos/res/layout/videoview.xml
@@ -0,0 +1,14 @@
+<?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"
+    >
+    
+    <VideoView 
+        android:id="@+id/surface_view" 
+        android:layout_width="320px"
+        android:layout_height="240px"
+    />
+    
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/visibility_1.xml b/samples/ApiDemos/res/layout/visibility_1.xml
new file mode 100644
index 0000000..ad94602
--- /dev/null
+++ b/samples/ApiDemos/res/layout/visibility_1.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates changing view visibility. See corresponding Java code. -->
+
+<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:orientation="vertical"
+      android:background="@drawable/box"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+
+      <TextView
+          android:background="@drawable/red"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/visibility_1_view_1"/>
+
+      <TextView android:id="@+id/victim"
+          android:background="@drawable/green"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/visibility_1_view_2"/>
+
+      <TextView
+          android:background="@drawable/blue"
+          android:layout_width="fill_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/visibility_1_view_3"/>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <Button android:id="@+id/vis"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/visibility_1_vis"/>
+
+        <Button android:id="@+id/invis"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/visibility_1_invis"/>
+
+        <Button android:id="@+id/gone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/visibility_1_gone"/>
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/voice_recognition.xml b/samples/ApiDemos/res/layout/voice_recognition.xml
new file mode 100644
index 0000000..2db4a72
--- /dev/null
+++ b/samples/ApiDemos/res/layout/voice_recognition.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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.
+ -->
+
+<!-- This activity displays UI for launching voice recognition -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+    
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="4dip"
+        android:text="@string/voice_recognition_prompt" />
+        
+    <Button android:id="@+id/btn_speak"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/speak_button" />
+        
+    <ListView android:id="@+id/list"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" />
+
+ </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/webview_1.xml b/samples/ApiDemos/res/layout/webview_1.xml
new file mode 100644
index 0000000..91fca39
--- /dev/null
+++ b/samples/ApiDemos/res/layout/webview_1.xml
@@ -0,0 +1,79 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+    
+    
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+        
+        <WebView android:id="@+id/wv1"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv2"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv3"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv4"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv5"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv6"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+    
+        <WebView android:id="@+id/wv7"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv8"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv9"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+            
+        <WebView android:id="@+id/wv10"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            />
+    </LinearLayout>
+        
+ </ScrollView>        
diff --git a/samples/ApiDemos/res/menu/category_order.xml b/samples/ApiDemos/res/menu/category_order.xml
new file mode 100644
index 0000000..cb2dde9
--- /dev/null
+++ b/samples/ApiDemos/res/menu/category_order.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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">
+
+    <!-- This group uses the default category. -->
+    <group android:id="@+id/most_used_items">
+    
+        <item android:id="@+id/last_most_item"
+            android:orderInCategory="10"
+            android:title="@string/last_most_often" />
+    
+        <item android:id="@+id/middle_most_item"
+            android:orderInCategory="7"
+            android:title="@string/middle_most_often" />
+    
+        <item android:id="@+id/first_most_item"
+            android:orderInCategory="4"
+            android:title="@string/first_most_often" />
+    
+    </group>
+    
+    <!-- This group uses the secondary category, which is used for less oftenly used items.
+         Notice these items will show up after the above items.
+         (Furthermore, notice how the orders in each category are independent from the other
+         category.) -->
+    <group android:id="@+id/least_used_items"
+        android:menuCategory="secondary">
+        
+        <item android:id="@+id/last_least_item"
+            android:orderInCategory="3"
+            android:title="@string/last_least_often" />
+    
+        <item android:id="@+id/middle_least_item"
+            android:orderInCategory="2"
+            android:title="@string/middle_least_often" />
+    
+        <item android:id="@+id/first_least_item"
+            android:orderInCategory="0"
+            android:title="@string/first_least_often" />
+    
+    </group>
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/checkable.xml b/samples/ApiDemos/res/menu/checkable.xml
new file mode 100644
index 0000000..17fae65
--- /dev/null
+++ b/samples/ApiDemos/res/menu/checkable.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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">
+
+    <!-- Checkable items appear only in submenus or context menus. -->
+
+    <!-- Carefully look at the attribute name checkableBehavior on groups, but
+         the attribute name checkable on items. The checkableBehavior encompasses
+         the number of items that will be checkable within that group. -->
+
+    <item android:title="None">
+        <menu>
+            <!-- The none checkableBehavior is default, but we explicitly show it here. -->
+            <group android:id="@+id/noncheckable_group"
+                    android:checkableBehavior="none">
+                <!-- Notice how these items inherit from the group. -->
+                <item android:id="@+id/noncheckable_item_1"
+                        android:title="@string/item_1" />
+                <item android:id="@+id/noncheckable_item_2"
+                        android:title="@string/item_2" />
+                <item android:id="@+id/noncheckable_item_3"
+                        android:title="@string/item_3" />
+            </group>
+        </menu>
+    </item>
+
+    <item android:title="All">
+        <menu>
+            <group android:id="@+id/checkable_group"
+                    android:checkableBehavior="all">
+                <!-- Notice how these items inherit from the group. -->
+                <item android:id="@+id/checkable_item_1"
+                        android:title="@string/item_1" />
+                <item android:id="@+id/checkable_item_2"
+                        android:title="@string/item_2"
+                        android:checked="true" />
+                <item android:id="@+id/checkable_item_3"
+                        android:title="@string/item_3"
+                        android:checked="true" />
+            </group>
+        </menu>
+    </item>
+
+    <item android:title="Single">
+        <menu>
+            <group android:id="@+id/exclusive_checkable_group"
+                    android:checkableBehavior="single">
+                <!-- Notice how these items inherit from the group. -->
+                <item android:id="@+id/exclusive_checkable_item_1"
+                        android:title="@string/item_1" />
+                <item android:id="@+id/exclusive_checkable_item_2"
+                        android:title="@string/item_2" />
+                <item android:id="@+id/exclusive_checkable_item_3"
+                        android:title="@string/item_3"
+                        android:checked="true" />
+            </group>
+        </menu>
+    </item>
+
+    <item android:title="All without group">
+        <menu>
+            <!-- Notice how these items have each set. -->
+            <item android:id="@+id/nongroup_checkable_item_1"
+                    android:title="@string/item_1"
+                    android:checkable="true" />
+            <item android:id="@+id/nongroup_checkable_item_2"
+                    android:title="@string/item_2"
+                    android:checkable="true"
+                    android:checked="true" />
+            <item android:id="@+id/nongroup_checkable_item_3"
+                    android:title="@string/item_3"
+                    android:checkable="true"
+                    android:checked="true" />
+        </menu>
+    </item>
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/disabled.xml b/samples/ApiDemos/res/menu/disabled.xml
new file mode 100644
index 0000000..647ec2e
--- /dev/null
+++ b/samples/ApiDemos/res/menu/disabled.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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/enabled_item"
+        android:title="Enabled"
+        android:icon="@drawable/stat_happy" />
+
+    <item android:id="@+id/disabled_item"
+        android:title="Disabled"
+        android:enabled="false"
+        android:icon="@drawable/stat_sad" />
+
+    <item android:id="@+id/enabled_item_2"
+        android:title="Enabled"
+        android:icon="@drawable/stat_happy" />
+
+    <item android:id="@+id/disabled_item_2"
+        android:title="Disabled"
+        android:enabled="false"
+        android:icon="@drawable/stat_sad" />
+
+    <item android:id="@+id/enabled_item_3"
+        android:title="Enabled"
+        android:icon="@drawable/stat_happy" />
+
+    <item android:id="@+id/disabled_item_3"
+        android:title="Disabled"
+        android:enabled="false"
+        android:icon="@drawable/stat_sad" />
+
+    <item android:id="@+id/enabled_item_4"
+        android:title="Enabled"
+        android:icon="@drawable/stat_happy" />
+
+    <item android:id="@+id/disabled_item_4"
+        android:title="Disabled"
+        android:enabled="false"
+        android:icon="@drawable/stat_sad" />
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/groups.xml b/samples/ApiDemos/res/menu/groups.xml
new file mode 100644
index 0000000..46c04f5
--- /dev/null
+++ b/samples/ApiDemos/res/menu/groups.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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/browser_visibility"
+        android:title="@string/browser_visibility" />
+
+    <group android:id="@+id/browser">
+    
+        <item android:id="@+id/refresh"
+            android:title="@string/browser_refresh" />
+    
+        <item android:id="@+id/bookmark"
+            android:title="@string/browser_bookmark" />
+    
+    </group>
+
+    <item android:id="@+id/email_visibility"
+        android:title="@string/email_visibility" />
+
+    <group android:id="@+id/email">
+    
+        <item android:id="@+id/reply"
+            android:title="@string/email_reply" />
+    
+        <item android:id="@+id/forward"
+            android:title="@string/email_forward" />
+    
+    </group>
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/order.xml b/samples/ApiDemos/res/menu/order.xml
new file mode 100644
index 0000000..c73121f
--- /dev/null
+++ b/samples/ApiDemos/res/menu/order.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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">
+
+    <!-- These are in reverse order in this resource, but the orderInCategory attribute will
+         order them for the menu (they all have the same default category). -->
+
+    <item android:id="@+id/fourth_item"
+        android:orderInCategory="3"
+        android:title="Fourth" />
+
+    <item android:id="@+id/third_item"
+        android:orderInCategory="2"
+        android:title="Third" />
+
+    <item android:id="@+id/second_item"
+        android:orderInCategory="1"
+        android:title="Second" />
+
+    <item android:id="@+id/first_item"
+        android:orderInCategory="0"
+        android:title="First" />
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/shortcuts.xml b/samples/ApiDemos/res/menu/shortcuts.xml
new file mode 100644
index 0000000..b5e938a
--- /dev/null
+++ b/samples/ApiDemos/res/menu/shortcuts.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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/invisible_item"
+        android:visible="false"
+        android:alphabeticShortcut="i"
+        android:title="Invisible item" />
+
+    <item android:id="@+id/a_item"
+        android:alphabeticShortcut="a"
+        android:title="Alvin" />
+
+    <item android:id="@+id/b_item"
+        android:alphabeticShortcut="b"
+        android:title="Bart" />
+
+    <item android:id="@+id/c_item"
+        android:alphabeticShortcut="c"
+        android:title="Chris" />
+
+    <item android:id="@+id/d_item"
+        android:alphabeticShortcut="d"
+        android:title="David" />
+
+    <item android:id="@+id/e_item"
+        android:alphabeticShortcut="e"
+        android:title="Eric" />
+
+    <item android:id="@+id/f_item"
+        android:alphabeticShortcut="f"
+        android:title="Frank" />
+
+    <item android:id="@+id/g_item"
+        android:alphabeticShortcut="g"
+        android:title="Gary" />
+
+    <item android:id="@+id/h_item"
+        android:alphabeticShortcut="h"
+        android:title="Henry" />
+
+    <item android:id="@+id/excl_item"
+        android:alphabeticShortcut="!"
+        android:title="Exclamation" />
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/submenu.xml b/samples/ApiDemos/res/menu/submenu.xml
new file mode 100644
index 0000000..24eff76
--- /dev/null
+++ b/samples/ApiDemos/res/menu/submenu.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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:title="Normal 1" />
+
+    <item android:id="@+id/submenu"
+        android:title="Emotions">
+
+        <menu>        
+
+            <item android:id="@+id/happy"
+                android:title="Happy"
+                android:icon="@drawable/stat_happy" />
+        
+            <item android:id="@+id/neutral"
+                android:title="Neutral"
+                android:icon="@drawable/stat_neutral" />
+        
+            <item android:id="@+id/sad"
+                android:title="Sad"
+                android:icon="@drawable/stat_sad" />
+        
+        </menu>
+    
+    </item>
+
+    <item android:title="Normal 2" />
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/title_icon.xml b/samples/ApiDemos/res/menu/title_icon.xml
new file mode 100644
index 0000000..72030a9
--- /dev/null
+++ b/samples/ApiDemos/res/menu/title_icon.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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/happy"
+        android:title="Happy"
+        android:icon="@drawable/stat_happy" />
+
+    <item android:id="@+id/neutral"
+        android:title="Neutral"
+        android:icon="@drawable/stat_neutral" />
+
+    <item android:id="@+id/sad"
+        android:title="Sad"
+        android:icon="@drawable/stat_sad" />
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/title_only.xml b/samples/ApiDemos/res/menu/title_only.xml
new file mode 100644
index 0000000..44162b1
--- /dev/null
+++ b/samples/ApiDemos/res/menu/title_only.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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/jump"
+        android:title="@string/jump" />
+
+    <item android:id="@+id/dive"
+        android:title="@string/dive" />
+
+</menu>
diff --git a/samples/ApiDemos/res/menu/visible.xml b/samples/ApiDemos/res/menu/visible.xml
new file mode 100644
index 0000000..b41698d
--- /dev/null
+++ b/samples/ApiDemos/res/menu/visible.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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/visible_item"
+        android:title="Visible"
+        android:alphabeticShortcut="a" />
+
+    <item android:id="@+id/hidden_item"
+        android:title="Hidden"
+        android:visible="false"
+        android:alphabeticShortcut="b" />
+
+    <group android:id="@+id/hidden_group"
+        android:visible="false">
+    
+        <item android:id="@+id/hidden_by_group"
+            android:title="Hidden by group"
+            android:alphabeticShortcut="c" />
+    
+    </group>
+
+</menu>
diff --git a/samples/ApiDemos/res/raw/test_cbr.mp3 b/samples/ApiDemos/res/raw/test_cbr.mp3
new file mode 100755
index 0000000..7204d27
--- /dev/null
+++ b/samples/ApiDemos/res/raw/test_cbr.mp3
Binary files differ
diff --git a/samples/ApiDemos/res/values/arrays.xml b/samples/ApiDemos/res/values/arrays.xml
new file mode 100644
index 0000000..ca3003f
--- /dev/null
+++ b/samples/ApiDemos/res/values/arrays.xml
@@ -0,0 +1,88 @@
+<?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>
+    <!-- Used in View/Spinner1.java -->
+    <string-array name="colors">
+        <item>red</item>
+        <item>orange</item>
+        <item>yellow</item>
+        <item>green</item>
+        <item>blue</item>
+        <item>violet</item>
+    </string-array>
+    
+    <!-- Used in View/Spinner1.java -->
+    <string-array name="planets">
+        <item>Mercury</item>
+        <item>Venus</item>
+        <item>Earth</item>
+        <item>Mars</item>
+        <item>Jupiter</item>
+        <item>Saturn</item>
+        <item>Uranus</item>
+        <item>Neptune</item>
+        <item>Pluto</item>
+    </string-array>
+
+    <!-- Used in App/SearchInvoke.java -->
+    <string-array name="search_menuModes">
+        <item>Search Key</item>
+        <item>Menu Item</item>
+        <item>Type-To-Search</item>
+        <item>Disabled</item>
+    </string-array>
+    
+    <!-- Used in app/dialog examples -->
+    <string-array name="select_dialog_items">
+        <item>Command one</item>
+        <item>Command two</item>
+        <item>Command three</item>
+        <item>Command four</item>
+    </string-array>
+    
+    <string-array name="select_dialog_items2">
+        <item>Map</item>
+        <item>Satellite</item>
+        <item>Traffic</item>
+        <item>Street view</item>
+    </string-array>
+    
+    <string-array name="select_dialog_items3">
+        <item>Every Monday</item>
+        <item>Every Tuesday</item>
+        <item>Every Wednesday</item>
+        <item>Every Thursday</item>
+        <item>Every Friday</item>
+        <item>Every Saturday</item>
+        <item>Every Sunday</item>
+    </string-array>
+    
+    <!-- Used in app/menu examples -->
+    <string-array name="entries_list_preference">
+        <item>Alpha Option 01</item>
+        <item>Beta Option 02</item>
+        <item>Charlie Option 03</item>  
+    </string-array>
+
+    <!-- Used in app/menu examples -->
+    <string-array name="entryvalues_list_preference">
+        <item>alpha</item>
+        <item>beta</item>
+        <item>charlie</item>  
+    </string-array>
+    
+</resources>
diff --git a/samples/ApiDemos/res/values/attrs.xml b/samples/ApiDemos/res/values/attrs.xml
new file mode 100644
index 0000000..53f0034
--- /dev/null
+++ b/samples/ApiDemos/res/values/attrs.xml
@@ -0,0 +1,35 @@
+<?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>
+    <!-- These are the attributes that we want to retrieve from the theme
+         in app/PreferencesFromCode.java -->
+    <declare-styleable name="TogglePrefAttrs">
+        <attr name="android:preferenceLayoutChild" />
+    </declare-styleable>
+    
+    <!-- These are the attributes that we want to retrieve from the theme
+         in view/Gallery1.java -->
+    <declare-styleable name="Gallery1">
+        <attr name="android:galleryItemBackground" />
+    </declare-styleable>
+    
+     <declare-styleable name="LabelView">
+        <attr name="text" format="string" />
+        <attr name="textColor" format="color" />
+        <attr name="textSize" format="dimension" />
+    </declare-styleable>
+</resources>
diff --git a/samples/ApiDemos/res/values/colors.xml b/samples/ApiDemos/res/values/colors.xml
new file mode 100644
index 0000000..f2534d1
--- /dev/null
+++ b/samples/ApiDemos/res/values/colors.xml
@@ -0,0 +1,32 @@
+<?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>
+    <drawable name="red">#7f00</drawable>
+    <drawable name="blue">#770000ff</drawable>
+    <drawable name="green">#7700ff00</drawable>
+	<drawable name="yellow">#77ffff00</drawable>
+	
+	<drawable name="screen_background_black">#ff000000</drawable>
+    <drawable name="translucent_background">#e0000000</drawable>
+    <drawable name="transparent_background">#00000000</drawable>
+
+    <color name="solid_red">#f00</color>
+    <color name="solid_blue">#0000ff</color>
+    <color name="solid_green">#f0f0</color>
+    <color name="solid_yellow">#ffffff00</color>
+
+</resources>
diff --git a/samples/ApiDemos/res/values/ids.xml b/samples/ApiDemos/res/values/ids.xml
new file mode 100644
index 0000000..17a3895
--- /dev/null
+++ b/samples/ApiDemos/res/values/ids.xml
@@ -0,0 +1,19 @@
+<?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>
+  <item type="id" name="snack" />
+</resources>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
new file mode 100644
index 0000000..bd1b0a3
--- /dev/null
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -0,0 +1,824 @@
+<?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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="activity_sample_code">API Demos</string>
+
+    <!-- =============================== -->
+    <!--  app/activity examples strings  -->
+    <!-- =============================== -->
+
+    <string name="tabs_1_tab_1">tab1</string>
+    <string name="tabs_1_tab_2">tab2</string>
+    <string name="tabs_1_tab_3">tab3</string>
+
+    <string name="activity_hello_world">App/Activity/<b>Hello <i>World</i></b></string>
+    <string name="hello_world"><b>Hello, <i>World!</i></b></string>
+
+    <string name="activity_dialog">App/Activity/Dialog</string>
+    <string name="dialog_activity_text">Example of how you can use the
+            Theme.Dialog theme to make an activity that looks like a
+            dialog.</string>
+
+    <string name="activity_custom_dialog">App/Activity/Custom Dialog</string>
+    <string name="custom_dialog_activity_text">Example of how you can use a
+            custom Theme.Dialog theme to make an activity that looks like a
+            customized dialog, here with an ugly frame.</string>
+
+    <string name="activity_translucent">App/Activity/Translucent</string>
+    <string name="translucent_background">Example of how you can make an
+            activity have a translucent background, compositing over
+            whatever is behind it.</string>
+
+    <string name="activity_translucent_blur">App/Activity/Translucent Blur</string>
+
+    <string name="activity_save_restore">App/Activity/Save &amp; Restore State</string>
+    <string name="save_restore_msg">Demonstration of saving and restoring activity state in onSaveInstanceState() and onCreate().</string>
+    <string name="saves_state">This text field saves its state:</string>
+    <string name="no_saves_state">This text field does not save its state:</string>
+    <string name="initial_text">Initial text.</string>
+
+    <string name="activity_persistent">App/Activity/Persistent State</string>
+    <string name="persistent_msg">Demonstration of persistent activity state with getPreferences(0).edit() and getPreferences(0).</string>
+
+    <string name="activity_receive_result">App/Activity/Receive Result</string>
+    <string name="pick_result">Pick a result to send, or BACK to cancel.</string>
+    <string name="corky">Corky</string>
+    <string name="violet">Violet</string>
+
+    <string name="activity_forwarding">App/Activity/Forwarding</string>
+    <string name="forwarding">Press the button to go forward to the next activity.  This activity will stop, so you will no longer see it when going back.</string>
+    <string name="go">Go</string>
+    <string name="forward_target">Press back button and notice we don\'t see the previous activity.</string>
+
+    <string name="activity_redirect">App/Activity/Redirection</string>
+    <string name="redirect_enter">Press the button to start the example.  The next activity will conditionally redirect to another activity to collect data from the user.</string>
+    <string name="redirect_main">You now see the main activity running normally because the user text has been set to:</string>
+    <string name="clear_text">Clear and Exit</string>
+    <string name="new_text">New Text</string>
+    <string name="redirect_getter">Enter the text that will be used by the main activity.  Press back to cancel.</string>
+    <string name="apply">Apply</string>
+
+    <string name="activity_menu">App/Activity/Menu</string>
+    <string name="open_menu">Open menu</string>
+    <string name="close_menu">Close menu</string>
+    <string name="toggle_scenery">Toggle scenery</string>
+    <string name="toggle_dogs">Toggle dogs</string>
+    <string name="long_click_for_context_menu">Long click for context menu</string>
+
+    <string name="local_service_started">Local service has started</string>
+    <string name="local_service_stopped">Local service has stopped</string>
+    <string name="local_service_label">Sample Local Service</string>
+
+    <string name="activity_local_service_controller">App/Service/Local Service Controller</string>
+    <string name="local_service_controller">This demonstrates how you can implement persistent services that
+        may be started and stopped as desired.</string>
+    <string name="start_service">Start Service</string>
+    <string name="stop_service">Stop Service</string>
+
+    <string name="activity_local_service_binding">App/Service/Local Service Binding</string>
+    <string name="local_service_binding">This demonstrates how you can connect with a persistent
+        service.  Notice how it automatically starts for you, and play around with the
+        interaction between this and Local Service Controller.</string>
+    <string name="bind_service">Bind Service</string>
+    <string name="unbind_service">Unbind Service</string>
+    <string name="local_service_connected">Connected to local service</string>
+    <string name="local_service_disconnected">Disconnected from local service</string>
+
+    <string name="remote_service_started">Remote service has started</string>
+    <string name="remote_service_stopped">Remote service has stopped</string>
+    <string name="remote_service_label">Sample Remote Service</string>
+
+    <string name="activity_remote_service_controller">App/Service/Remote Service Controller</string>
+    <string name="remote_service_controller">This demonstrates how you can implement persistent services
+        running in a separate process that may be started and stopped as desired.</string>
+
+    <string name="activity_remote_service_binding">App/Service/Remote Service Binding</string>
+    <string name="remote_service_binding">This demonstrates how you can connect with a persistent
+        service running in another process.  Use the kill button to see what happens when
+        the process crashes.</string>
+    <string name="kill_process">Kill Process</string>
+    <string name="remote_service_connected">Connected to remote service</string>
+    <string name="remote_service_disconnected">Disconnected from remote service</string>
+    <string name="remote_call_failed">Failure calling remote service</string>
+
+    <string name="service_arguments_started">"Started with arguments: "</string>
+    <string name="service_arguments_stopped">Finished arguments,
+        stopping.</string>
+    <string name="service_start_arguments_label">Sample Service Start Arguments
+    </string>
+
+    <string name="activity_service_start_arguments_controller">App/Service/Service
+        Start Arguments Controller
+    </string>
+    <string name="service_start_arguments_controller">This demonstrates how
+        service can be started with arguments, and run until all arguments are
+        processed.
+    </string>
+    <string name="start1_service">Start with \"One\"</string>
+    <string name="start2_service">Start with \"Two\"</string>
+    <string name="start3_service">Start with \"Three\"</string>
+
+    <string name="one_shot_received">The one-shot alarm has gone off</string>
+    <string name="repeating_received">The repeating alarm has gone off</string>
+
+    <string name="activity_alarm_controller">App/Alarm/Alarm Controller</string>
+    <string name="alarm_controller">This demonstrates how to schedule and handle
+        one-shot and repeating alarms.</string>
+    <string name="one_shot_alarm">One Shot Alarm</string>
+    <string name="start_repeating_alarm">Start Repeating Alarm</string>
+    <string name="stop_repeating_alarm">Stop Repeating Alarm</string>
+    <string name="one_shot_scheduled">One-shot alarm will go off in 30 seconds based on
+        the real time clock.  Try changing the current time before then!</string>
+    <string name="repeating_scheduled">Repeating alarm will go off in 15 seconds and
+        every 15 seconds after based on the elapsed realtime clock</string>
+    <string name="repeating_unscheduled">Repeating alarm has been unscheduled</string>
+
+    <string name="alarm_service_started">The alarm service has started running</string>
+    <string name="alarm_service_finished">The alarm service has finished running</string>
+    <string name="alarm_service_label">Sample Alarm Service</string>
+
+    <string name="activity_alarm_service">App/Alarm/Alarm Service</string>
+    <string name="alarm_service">This demonstrates how to schedule a repeating
+        alarm that will initiate a long-lived operation through a service.</string>
+    <string name="start_alarm_service">Start Alarm Service</string>
+    <string name="stop_alarm_service">Stop Alarm Service</string>
+    <string name="alarm_service_scheduled">Alarm service will run now, and then every
+        30 seconds for 15 seconds</string>
+    <string name="alarm_service_unscheduled">Alarm service has been unscheduled</string>
+
+    <string name="activity_local_sample">App/Instrumentation/Local Sample</string>
+    <string name="local_sample">This demonstrates an Instrumentation that runs against
+        one of our own classes.  Note that this activity will be killed as
+        a side-effect of starting instrumentation on its own application.</string>
+
+    <string name="activity_contacts_filter">App/Instrumentation/Contacts Filter</string>
+    <string name="contacts_filter">This demonstrates an Instrumentation package that
+        launches the contacts list and simulates user events to filter it.</string>
+
+    <string name="pick_image_label">App/Activity/PickImage</string>
+    <string name="pick_image">Pick Image</string>
+
+    <string name="short_notification_text">Short notification</string>
+    <string name="long_notification_text">This is a long notification.  See, you might need a second more to read it.</string>
+    <string name="status_bar_notification_title">Sample Notification</string>
+
+    <string name="notifying_service_controller">This service will update a status bar notification
+                  every 5 seconds for a minute</string>
+
+    <string name="activity_custom_title">App/Activity/Custom Title</string>
+    <string name="custom_title_left">Left is best</string>
+    <string name="custom_title_right">Right is always right</string>
+    <string name="custom_title_left_button">Change Left</string>
+    <string name="custom_title_right_button">Change Right</string>
+
+    <string name="activity_reorder">App/Activity/Reorder Activities</string>
+    <string name="reorder_on_launch">This is the first of a sequence of four Activities.  A button on the fourth will use the Intent.FLAG_ACTIVITY_REORDER_TO_FRONT flag to bring the second of the activities to the front of the history stack. After that, proceeding back through the history should begin with the newly-frontmost second reorder activity, then the fourth, the third, and finally the first.</string>
+    <string name="reorder_launch_two">Go to the second</string>
+    <string name="reorder_two_text">This is the second in a sequence of four Activities.</string>
+    <string name="reorder_launch_three">Go to the third</string>
+    <string name="reorder_three_text">This is the third of a sequence of four Activities.</string>
+    <string name="reorder_launch_four">Go to the fourth</string>
+    <string name="reorder_four_text">This is the last in a sequence of four Activities.</string>
+    <string name="reorder_second_to_front">Bring the second in front</string>
+
+    <string name="menu_from_xml_title">App/Menu/Inflate from XML</string>
+    <string name="menu_from_xml_instructions_press_menu">Select a menu resource and press the menu key.</string>
+    <string name="menu_from_xml_instructions_go_back">If you want to choose another menu resource, go back and re-run this activity.</string>
+
+    <string name="voice_recognition">App/Voice Recognition</string>
+
+    <!-- ============================== -->
+    <!--  app/content examples strings  -->
+    <!-- ============================== -->
+
+    <string name="activity_styled_text">Content/Resources/<i>Styled</i> <b>Text</b></string>
+    <string name="styled_text_rsrc">Initialized from a resource:</string>
+    <string name="styled_text">Plain, <b>bold</b>, <i>italic</i>, <b><i>bold-italic</i></b></string>
+    <string name="styled_text_prog">Assigned programmatically:</string>
+
+    <string name="activity_read_asset">Content/Assets/Read Asset</string>
+
+    <string name="activity_themes">Content/Resources/Themes</string>
+    <string name="activity_resources">Content/Resources/Resources</string>
+
+    <!-- ============================== -->
+    <!--  app/intents examples strings     -->
+    <!-- ============================== -->
+    
+    <string name="activity_intents">App/Intents</string>
+    <string name="intents">Example of launching various Intents.</string>
+    <string name="get_music">Get Music</string>
+        
+    <!-- =================================== -->
+    <!--  app/notification examples strings  -->
+    <!-- =================================== -->
+
+    <string name="short_notification">Short notification.</string>
+    <string name="long_notification">Long notification.</string>
+    <string name="short_top_notification">Short top.</string>
+    <string name="short_bottom_notification">Short bottom.</string>
+    <string name="short_center_notification">Short center.</string>
+    <string name="short_left_notification">Short left.</string>
+    <string name="short_right_notification">Short right.</string>
+    <string name="custom_notification">Custom Notification:</string>
+    <string name="custom_notification_button">With a Button</string>
+
+    <string name="status_bar_notifications_icons_only">Icons only</string>
+    <string name="status_bar_notifications_icons_and_marquee">Icons and marquee</string>
+    <string name="status_bar_notifications_remote_views">Use remote views in balloon</string>
+    <string name="status_bar_notifications_defaults">Use default values where applicable</string>
+    <string name="status_bar_notifications_happy">:-)</string>
+    <string name="status_bar_notifications_ok">:-|</string>
+    <string name="status_bar_notifications_sad">:-(</string>
+    <string name="status_bar_notifications_happy_message">I am happy</string>
+    <string name="status_bar_notifications_ok_message">I am ok</string>
+    <string name="status_bar_notifications_sad_message">I am sad</string>
+    <string name="status_bar_notifications_clear">Clear notification</string>
+    <string name="status_bar_notifications_mood_title">Mood ring</string>
+    <string name="status_bar_notifications_default_sound">Sound</string>
+    <string name="status_bar_notifications_default_vibrate">Vibrate</string>
+    <string name="status_bar_notifications_default_all">All</string>
+
+    <!-- ============================== -->
+    <!--  app/dialog examples strings  -->
+    <!-- ============================== -->
+
+    <string name="activity_alert_dialog">App/Dialog</string>
+    <string name="alert_dialog_two_buttons">OK Cancel dialog with a message</string>
+    <string name="alert_dialog_two_buttons2">OK Cancel dialog with a long message</string>
+    <string name="alert_dialog_select_button">List dialog</string>
+    <string name="alert_dialog_single_choice">Single choice list</string>
+    <string name="alert_dialog_multi_choice">Repeat alarm</string>
+    <string name="alert_dialog_progress_button">Progress dialog</string>
+    <string name="alert_dialog_text_entry">Text Entry dialog</string>
+    <string name="alert_dialog_username">Name:</string>
+    <string name="alert_dialog_password">Password:</string>
+    <string name="alert_dialog_two_buttons_title">
+        Lorem ipsum dolor sit aie consectetur adipiscing\nPlloaso mako nuto
+        siwuf cakso dodtos anr koop.
+    </string>
+    <string name="alert_dialog_two_buttons_msg">Header title</string>
+    <string name="alert_dialog_two_buttons2_msg">
+        Plloaso mako nuto siwuf cakso dodtos anr koop a
+        cupy uf cak vux noaw yerw phuno. Whag schengos, uf efed, quiel
+        ba mada su otrenzr.\n\nSwipontgwook proudgs hus yag su ba dagarmidad.
+        Plasa maku noga wipont trenzsa schengos ent kaap zux comy.\n\nWipont trenz
+        kipg naar mixent phona. Cak pwico siructiun
+        ruous nust apoply tyu cak Uhex sisulutiun munityuw uw dseg
+    </string>
+    <string name="alert_dialog_ok">OK</string>
+    <string name="alert_dialog_hide">Hide</string>
+    <string name="alert_dialog_something">Something</string>
+    <string name="alert_dialog_cancel">Cancel</string>
+    <string name="alert_dialog_progress_text1">34<xliff:g id="percent">%</xliff:g></string>
+    <string name="alert_dialog_progress_text2">145/305 KB</string>
+
+    <string name="select_dialog">Header title</string>
+    <string name="select_dialog_show">List dialog</string>
+
+    <!-- ============================== -->
+    <!--  app/menu examples strings     -->
+    <!-- ============================== -->
+
+    <string name="last_most_often">Last most often</string>
+    <string name="middle_most_often">Middle most often</string>
+    <string name="first_most_often">First most often</string>
+    <string name="last_least_often">Last least often</string>
+    <string name="middle_least_often">Middle least often</string>
+    <string name="first_least_often">First least often</string>
+    <string name="item_1">Item 1</string>
+    <string name="item_2">Item 2</string>
+    <string name="item_3">Item 3</string>
+    <string name="browser_visibility">Browser visibility</string>
+    <string name="browser_refresh">Refresh</string>
+    <string name="browser_bookmark">Bookmark</string>
+    <string name="email_visibility">Email visibility</string>
+    <string name="email_reply">Reply</string>
+    <string name="email_forward">Forward</string>
+    <string name="jump">Jump</string>
+    <string name="dive">Dive</string>
+
+    <!-- ============================== -->
+    <!--  app/menu examples strings     -->
+    <!-- ============================== -->
+
+    <string name="preferences_from_xml">App/Preferences/1. Preferences from XML</string>
+    <string name="launching_preferences">App/Preferences/2. Launching preferences</string>
+    <string name="preference_dependencies">App/Preferences/3. Preference dependencies</string>
+    <string name="default_values">App/Preferences/4. Default values</string>
+    <string name="preferences_from_code">App/Preferences/5. Preferences from code</string>
+    <string name="advanced_preferences">App/Preferences/6. Advanced preferences</string>
+
+    <string name="launch_preference_activity">Launch PreferenceActivity</string>
+    <string name="counter_value_is">The counter value is</string>
+
+    <string name="inline_preferences">In-line preferences</string>
+    <string name="dialog_based_preferences">Dialog-based preferences</string>
+    <string name="launch_preferences">Launch preferences</string>
+    <string name="preference_attributes">Preference attributes</string>
+
+    <string name="title_toggle_preference">Toggle preference</string>
+    <string name="summary_toggle_preference">This is a toggle button</string>
+
+    <string name="title_checkbox_preference">Checkbox preference</string>
+    <string name="summary_checkbox_preference">This is a checkbox</string>
+
+    <string name="title_yesno_preference">Yes or no preference</string>
+    <string name="summary_yesno_preference">An example that uses a yes/no dialog</string>
+    <string name="dialog_title_yesno_preference">Do you like bananas?</string>
+
+    <string name="title_edittext_preference">Edit text preference</string>
+    <string name="summary_edittext_preference">An example that uses an edit text dialog</string>
+    <string name="dialog_title_edittext_preference">Enter your favorite animal</string>
+
+    <string name="title_list_preference">List preference</string>
+    <string name="summary_list_preference">An example that uses a list dialog</string>
+    <string name="dialog_title_list_preference">Choose one</string>
+
+    <string name="title_screen_preference">Screen preference</string>
+    <string name="summary_screen_preference">Shows another screen of preferences</string>
+
+    <string name="title_next_screen_toggle_preference">Toggle preference</string>
+    <string name="summary_next_screen_toggle_preference">Preference that is on the next screen but same hierarchy</string>
+
+    <string name="title_intent_preference">Intent preference</string>
+    <string name="summary_intent_preference">Launches an Activity from an Intent</string>
+
+    <string name="title_my_preference">My preference</string>
+    <string name="summary_my_preference">This is a custom counter preference</string>
+
+    <string name="title_advanced_toggle_preference">Haunted preference</string>
+    <string name="summary_on_advanced_toggle_preference">I'm on! :)</string>
+    <string name="summary_off_advanced_toggle_preference">I'm off! :(</string>
+
+    <string name="title_parent_preference">Parent toggle</string>
+    <string name="summary_parent_preference">This is visually a parent</string>
+    <string name="title_child_preference">Child toggle</string>
+    <string name="summary_child_preference">This is visually a child</string>
+
+    <string name="example_preference_dependency">Example preference dependency</string>
+    <string name="title_wifi">WiFi</string>
+    <string name="title_wifi_settings">WiFi settings</string>
+
+    <string name="default_value_list_preference">beta</string>
+    <string name="default_value_edittext_preference">Default value</string>
+
+    <!-- ============================== -->
+    <!--  app/search examples strings  -->
+    <!-- ============================== -->
+
+    <string name="search_invoke">App/Search/Invoke Search</string>
+    <string name="msg_search">This activity shows a few different ways to invoke search, and inserts context-specific data for use by the search activity.</string>
+    <string name="search_sect_invocation">Ways to invoke search</string>
+    <string name="label_onsearchrequested">onSearchRequested()</string>
+    <string name="search_sect_options">Optional search parameters</string>
+    <string name="label_search_query_prefill">"Prefill query: "</string>
+    <string name="label_search_query_appdata">"App Data: "</string>
+
+    <string name="search_query_results">App/Search/Query Search Results</string>
+    <string name="msg_search_results">This activity accepts query strings via the ACTION_SEARCH intent.  In a full implementation, you would use the query string to select results from your data source, and present a list of those results to the user.</string>
+    <string name="label_search_query">"Query String: "</string>
+    <string name="label_search_appdata">"Query App Data: "</string>
+    <string name="label_search_deliveredby">"Activity Method: "</string>
+
+    <string name="search_label">Search Demo</string>
+    <string name="search_hint">Search Demo Hint</string>
+
+    <!-- ================================ -->
+    <!--  app/shortcuts examples strings  -->
+    <!-- ================================ -->
+
+    <string name="shortcuts">App/Launcher Shortcuts</string>
+    <string name="sample_shortcuts">ApiDemos</string>
+    <string name="shortcut_name">Sample</string>
+
+    <string name="msg_launcher_shortcuts">This activity creates shortcuts for the launcher (home screen), and receives intents from those shortcuts.  To try it, return to the launcher and long-press to create a shortcut.</string>
+    <string name="label_intent">Intent:</string>
+    
+    <!-- ============================== -->
+    <!--  app/voice recognition examples strings  -->
+    <!-- ============================== -->
+
+    <string name="voice_recognition_prompt">This activity demonstrates the voice recognition APIs.</string>
+    <string name="speak_button">Speak!</string>
+    <string name="voice_recognition_results">Results:</string>
+    
+    <!-- ============================ -->
+    <!--  graphics examples strings  -->
+    <!-- ============================ -->
+
+    <string name="hide_me">Hide Me!</string>
+
+    <!-- ============================ -->
+    <!--  media examples strings  -->
+    <!-- ============================ -->
+
+    <string name="local_video">Play Video from Local File</string>
+    <string name="stream_video">Play Streaming Video</string>
+    <string name="local_audio">Play Audio from Local File</string>
+    <string name="res_audio">Play Audio from Resources</string>
+
+    <!-- ============================ -->
+    <!--  views examples strings  -->
+    <!-- ============================ -->
+
+    <string name="linear_layout_8_vertical">Vertical</string>
+    <string name="linear_layout_8_horizontal">Horizontal</string>
+    <string name="linear_layout_8_top">Top</string>
+    <string name="linear_layout_8_middle">Middle</string>
+    <string name="linear_layout_8_bottom">Bottom</string>
+    <string name="linear_layout_8_left">Left</string>
+    <string name="linear_layout_8_center">Center</string>
+    <string name="linear_layout_8_right">Right</string>
+    <string name="linear_layout_10_from">From:</string>
+    <string name="linear_layout_10_to">To:</string>
+    <string name="list_7_nothing">Nothing\u2026</string>
+    <string name="radio_group_snack">Snack</string>
+    <string name="radio_group_selection">"You have selected: "</string>
+    <string name="radio_group_none">(none)</string>
+    <string name="table_layout_7_quit">Quit</string>
+    <string name="table_layout_7_ctrlq">Ctrl-Q</string>
+    <string name="table_layout_8_quit">Quit</string>
+    <string name="table_layout_8_ctrlq">Ctrl-Q</string>
+
+    <string name="seekbar_tracking_on">Tracking on</string>
+    <string name="seekbar_tracking_off">Tracking off</string>
+    <string name="seekbar_from_touch">from touch</string>
+
+    <string name="ratingbar_rating">Rating:</string>
+
+    <!-- ============================== -->
+    <!--  GoogleLogin examples strings  -->
+    <!-- ============================== -->
+    <string name="googlelogin_err">Use a better username and password, please.</string>
+
+
+    <!-- ================================== -->
+    <!--  initial strings for layout files  -->
+    <!-- ================================== -->
+    <string name="animation_1_instructions">Please enter your password:</string>
+    <string name="animation_2_text_1">Freedom</string>
+    <string name="animation_2_text_2">is nothing else but</string>
+    <string name="animation_2_text_3">a chance to be better.</string>
+    <string name="animation_2_text_4">— Albert Camus</string>
+    <string name="animation_2_instructions">Select an animation:</string>
+    <string name="autocomplete_1_instructions">Type in the text field for auto-completion.</string>
+    <string name="autocomplete_1_country">Country:</string>
+    <string name="autocomplete_1_focus">Give me Focus</string>
+    <string name="autocomplete_2_country">Country:</string>
+    <string name="autocomplete_2_focus">Give me Focus</string>
+    <string name="autocomplete_3_button_1">Scroll</string>
+    <string name="autocomplete_3_button_2">Down</string>
+    <string name="autocomplete_3_button_3">To</string>
+    <string name="autocomplete_3_button_4">See</string>
+    <string name="autocomplete_3_button_5">Auto</string>
+    <string name="autocomplete_3_button_6">Complete</string>
+    <string name="autocomplete_3_button_7">Text</string>
+    <string name="autocomplete_3_button_8">View</string>
+    <string name="autocomplete_3_button">Button</string>
+    <string name="autocomplete_3_country">Country:</string>
+    <string name="autocomplete_4_instructions">Type in the text field for auto-completion.</string>
+    <string name="autocomplete_4_name">Name:</string>
+    <string name="autocomplete_4_message">You must have contacts in your address book. Typing * will show all of your contacts.</string>
+    <string name="autocomplete_5_instructions">Type in the text field for auto-completion.</string>
+    <string name="autocomplete_5_hint">Typing * will show all of your contacts.</string>
+    <string name="autocomplete_5_name">Name:</string>
+    <string name="autocomplete_6_to">To:</string>
+    <string name="autocomplete_6_to_hint">To</string>
+    <string name="autocomplete_6_subject">Subject:</string>
+    <string name="autocomplete_7_instructions">Type in the text field for auto-completion by words.</string>
+    <string name="autocomplete_7_country">Country:</string>
+    <string name="autocomplete_7_focus">Give me Focus</string>
+    <string name="baseline_1_label">Label:</string>
+    <string name="baseline_1_button">Button</string>
+    <string name="baseline_1_bigger">Bigger</string>
+    <string name="baseline_2_label">Label:</string>
+    <string name="baseline_2_button">Button</string>
+    <string name="baseline_2_bigger">Bigger</string>
+    <string name="baseline_3_label">Label:</string>
+    <string name="baseline_3_button">Button</string>
+    <string name="baseline_3_bigger">Bigger</string>
+    <string name="baseline_3_explanation">This example shows that baseline alignment has no effect when the layout gravity is set to center_vertical.</string>
+    <string name="baseline_4_label">Label:</string>
+    <string name="baseline_4_button">Button</string>
+    <string name="baseline_4_bigger">Bigger</string>
+    <string name="baseline_4_label_2">Label Again</string>
+    <string name="baseline_4_label_3">Label Me</string>
+    <string name="baseline_6_multi_line">This is a\nmulti-line field.</string>
+    <string name="baseline_6_baseline">Baseline Aligned</string>
+    <string name="baseline_7_fat">Big and bold</string>
+    <string name="baseline_7_lean">Slim and slick.</string>
+    <string name="baseline_nested_1_label">label</string>
+    <string name="controls_1_save">Save</string>
+    <string name="controls_1_checkbox_1">Checkbox 1</string>
+    <string name="controls_1_checkbox_2">Checkbox 2</string>
+    <string name="controls_1_radiobutton_1">RadioButton 1</string>
+    <string name="controls_1_radiobutton_2">RadioButton 2</string>
+    <string name="controls_1_star">Star</string>
+    <string name="focus_1_message">Service not running</string>
+    <string name="focus_1_placeholder">placeholder</string>
+    <string name="focus_2_left">left</string>
+    <string name="focus_2_jump">jump over me from L to R</string>
+    <string name="focus_2_right">right</string>
+    <string name="focus_3_left">left</string>
+    <string name="focus_3_right">right</string>
+    <string name="focus_3_top">top</string>
+    <string name="focus_3_bottom">bottom</string>
+    <string name="gallery_2_text">Testing</string>
+    <string name="googlelogin_login">Login</string>
+    <string name="googlelogin_bad_login">Bad Login</string>
+    <string name="googlelogin_clear">Clear Credentials</string>
+    <string name="googlelogin_user">Username:</string>
+    <string name="layout_animation_name">Name:</string>
+    <string name="layout_animation_lastname">Last Name:</string>
+    <string name="layout_animation_phone">Phone:</string>
+    <string name="layout_animation_address">Address:</string>
+    <string name="linear_layout_1_top">This is the top view.</string>
+    <string name="linear_layout_1_middle">This is the middle view. It has more text in it than either the top view or the bottom view.</string>
+    <string name="linear_layout_1_bottom">This is the bottom view.</string>
+    <string name="linear_layout_2_top">This is the top view.</string>
+    <string name="linear_layout_2_middle">This is the middle view. It has more text in it than either the top view or the bottom view.</string>
+    <string name="linear_layout_2_bottom">This is the bottom view.</string>
+    <string name="linear_layout_3_top">This is the top view.</string>
+    <string name="linear_layout_3_middle">This is the middle view. It has more text in it than either the top view or the bottom view.</string>
+    <string name="linear_layout_3_bottom">This is the bottom view.</string>
+    <string name="linear_layout_5_instructions">Type Here:</string>
+    <string name="linear_layout_5_cancel">Cancel</string>
+    <string name="linear_layout_5_ok">OK</string>
+    <string name="linear_layout_6_one">One</string>
+    <string name="linear_layout_6_two">Two</string>
+    <string name="linear_layout_6_three">This is the third one</string>
+    <string name="linear_layout_6_four">Four</string>
+    <string name="linear_layout_7_small">Not much text</string>
+    <string name="linear_layout_7_big">A lot more text than any of the other columns. This column should set the height of the linear layout.</string>
+    <string name="linear_layout_7_wrap">wrap_content</string>
+    <string name="linear_layout_8_a">A</string>
+    <string name="linear_layout_8_b">B</string>
+    <string name="linear_layout_8_c">C</string>
+    <string name="linear_layout_9_button">Button</string>
+    <string name="link_text_auto"><b>text1:</b> This is some text.  In
+      this text are some things that are actionable.  For instance,
+      you can click on http://www.google.com and it will launch the
+      web browser.  You can click on google.com too.  And, if you
+      click on (415) 555-1212 it should dial the phone.
+    </string>
+    <string name="link_text_manual"><b>text2:</b> This is some other
+      text, with a <a href="http://www.google.com">link</a> specified
+      via an &lt;a&gt; tag.  Use a \"tel:\" URL
+      to <a href="tel:4155551212">dial a phone number</a>.
+    </string>
+    <string name="list_8_new_photo">New photo</string>
+    <string name="list_8_clear_photos">Clear photos</string>
+    <string name="list_8_no_photos">No photos</string>
+    <string name="progressbar_1_plus">+</string>
+    <string name="progressbar_1_minus">-</string>
+    <string name="progressbar_1_default_progress">Default progress:</string>
+    <string name="progressbar_1_secondary_progress">Secondary progress:</string>
+    <string name="progressbar_3_progress">Show Progress</string>
+    <string name="progressbar_3_indeterminate">Show Indeterminate</string>
+    <string name="progressbar_3_indeterminate_no_title">Show Indeterminate No Title</string>
+    <string name="progressbar_4_toggle">Toggle Indeterminate</string>
+    <string name="radio_group_1_breakfast">Breakfast</string>
+    <string name="radio_group_1_lunch">Lunch</string>
+    <string name="radio_group_1_dinner">Dinner</string>
+    <string name="radio_group_1_all">All of them</string>
+    <string name="radio_group_1_selection">You have selected: (none)</string>
+    <string name="radio_group_1_clear">Clear</string>
+    <string name="receive_result_instructions">Press the button to get an activity result, which will be displayed here:</string>
+    <string name="receive_result_result">Get Result</string>
+    <string name="relative_layout_1_top">Top</string>
+    <string name="relative_layout_1_bottom">Bottom</string>
+    <string name="relative_layout_1_center">center_vertical</string>
+    <string name="relative_layout_2_instructions">Type here:</string>
+    <string name="relative_layout_2_ok">Ok</string>
+    <string name="relative_layout_2_cancel">Cancel</string>
+    <string name="scroll_view_1_text_1">Text View 1</string>
+    <string name="scroll_view_1_button_1">Button 1</string>
+    <string name="scroll_view_1_text_2">Text View 2</string>
+    <string name="scroll_view_1_button_2">Button 2</string>
+    <string name="scroll_view_1_text_3">Text View 3</string>
+    <string name="scroll_view_1_button_3">Button 3</string>
+    <string name="scroll_view_1_text_4">Text View 4</string>
+    <string name="scroll_view_1_button_4">Button 4</string>
+    <string name="scroll_view_1_text_5">Text View 5</string>
+    <string name="scroll_view_1_button_5">Button 5</string>
+    <string name="scroll_view_1_text_6">Text View 6</string>
+    <string name="scroll_view_1_button_6">Button 6</string>
+    <string name="scroll_view_2_text_1">Text View 1</string>
+    <string name="scroll_view_2_button_1">Button 1</string>
+    <string name="scrollbar_1_text">Lorem ipsum dolor sit amet.</string>
+    <string name="scrollbar_2_text">Lorem ipsum dolor sit amet.</string>
+    <string name="scrollbar_3_text">
+ The Android platform is a software stack for mobile devices including an
+ operating system, middleware and key applications. Developers can create
+ applications for the platform using the Android SDK. Applications are written
+ using the Java programming language and run on Dalvik, a custom virtual
+ machine designed for embedded use which runs on top of a Linux kernel.
+
+ If you want to know how to develop applications for Android, you're in the
+ right place. This site provides a variety of documentation that will help you
+ learn about Android and develop mobile applications for the platform.
+
+ An early look at the the Android SDK is also available. It includes sample
+ projects with source code, development tools, an emulator, and of course all
+ the libraries you'll need to build an Android application. What would it take
+ to build a better mobile phone?
+    </string>
+    <string name="spinner_1_color">Color:</string>
+    <string name="spinner_1_planet">Planet:</string>
+    <string name="spinner_1_color_prompt">Choose a color</string>
+    <string name="spinner_1_planet_prompt">Choose a planet</string>
+    <string name="table_layout_1_star">*</string>
+    <string name="table_layout_1_triple_star">***</string>
+    <string name="table_layout_1_open">Open\u2026</string>
+    <string name="table_layout_1_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_1_save">Save As\u2026</string>
+    <string name="table_layout_1_save_shortcut">(Save Document)</string>
+    <string name="table_layout_1_quit">Quit Application</string>
+    <string name="table_layout_1_quit_shortcut">Ctrl-Shift-Q</string>
+    <string name="table_layout_2_path_1">~/path/to/file/to/open</string>
+    <string name="table_layout_2_path_2">~/.profile</string>
+    <string name="table_layout_2_open">Open</string>
+    <string name="table_layout_2_save">Save</string>
+    <string name="table_layout_2_save_all">Save All</string>
+    <string name="table_layout_3_star">*</string>
+    <string name="table_layout_3_triple_star">***</string>
+    <string name="table_layout_3_open">Open\u2026</string>
+    <string name="table_layout_3_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_3_save">Save As\u2026</string>
+    <string name="table_layout_3_save_shortcut">(Save Document)</string>
+    <string name="table_layout_3_too_long">Too Long</string>
+    <string name="table_layout_3_quit">Quit Application</string>
+    <string name="table_layout_3_quit_shortcut">Ctrl-Shift-Q</string>
+    <string name="table_layout_4_open">Open\u2026</string>
+    <string name="table_layout_4_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_4_save">Save As\u2026</string>
+    <string name="table_layout_4_save_shortcut">Ctrl-Shift-S</string>
+    <string name="table_layout_5_open">Open\u2026</string>
+    <string name="table_layout_5_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_5_save">Save\u2026</string>
+    <string name="table_layout_5_save_shortcut">Ctrl-S</string>
+    <string name="table_layout_5_save_as">Save As\u2026</string>
+    <string name="table_layout_5_save_as_shortcut">Ctrl-Shift-S</string>
+    <string name="table_layout_5_import">Import\u2026</string>
+    <string name="table_layout_5_export">Export\u2026</string>
+    <string name="table_layout_5_export_shortcut">Ctrl-E</string>
+    <string name="table_layout_5_quit">Quit\u2026</string>
+    <string name="table_layout_6_x">X</string>
+    <string name="table_layout_6_open">Open\u2026</string>
+    <string name="table_layout_6_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_6_save">Save\u2026</string>
+    <string name="table_layout_6_save_shortcut">Ctrl-S</string>
+    <string name="table_layout_6_save_as">Save As\u2026</string>
+    <string name="table_layout_6_save_as_shortcut">Ctrl-Shift-S</string>
+    <string name="table_layout_6_import">Import\u2026</string>
+    <string name="table_layout_6_export">Export\u2026</string>
+    <string name="table_layout_6_export_shortcut">Ctrl-E</string>
+    <string name="table_layout_6_quit">Quit\u2026</string>
+    <string name="table_layout_7_x">X</string>
+    <string name="table_layout_7_open">Open\u2026</string>
+    <string name="table_layout_7_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_7_save">Save\u2026</string>
+    <string name="table_layout_7_save_shortcut">Ctrl-S</string>
+    <string name="table_layout_7_save_as">Save As\u2026</string>
+    <string name="table_layout_7_save_as_shortcut">Ctrl-Shift-S</string>
+    <string name="table_layout_7_import">Import\u2026</string>
+    <string name="table_layout_7_export">Export\u2026</string>
+    <string name="table_layout_7_export_shortcut">Ctrl-E</string>
+    <string name="table_layout_7_toggle_checkmarks">Toggle Checkmarks</string>
+    <string name="table_layout_7_toggle_shortcuts">Toggle Shortcuts</string>
+    <string name="table_layout_8_x">X</string>
+    <string name="table_layout_8_open">Open\u2026</string>
+    <string name="table_layout_8_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_8_save">Save\u2026</string>
+    <string name="table_layout_8_save_shortcut">Ctrl-S</string>
+    <string name="table_layout_8_save_as">Save As\u2026</string>
+    <string name="table_layout_8_save_as_shortcut">Ctrl-Shift-S</string>
+    <string name="table_layout_8_import">Import\u2026</string>
+    <string name="table_layout_8_export">Export\u2026</string>
+    <string name="table_layout_8_export_shortcut">Ctrl-E</string>
+    <string name="table_layout_8_toggle_stretch">Toggle Stretch</string>
+    <string name="table_layout_9_open">Open\u2026</string>
+    <string name="table_layout_9_open_shortcut">Ctrl-O</string>
+    <string name="table_layout_9_save">Save\u2026</string>
+    <string name="table_layout_9_save_shortcut">Ctrl-S</string>
+    <string name="table_layout_9_save_as">Save As\u2026</string>
+    <string name="table_layout_9_save_as_shortcut">Ctrl-Shift-S</string>
+    <string name="table_layout_9_save_all">Save All And Do A Lot Of Stuff Just To Be Too Long For This Screen Because It Is A Test After All</string>
+    <string name="table_layout_9_save_all_shortcut">Ctrl-E</string>
+    <string name="table_layout_9_import">Import\u2026</string>
+    <string name="table_layout_9_export">Export\u2026</string>
+    <string name="table_layout_9_export_shortcut">Ctrl-E</string>
+    <string name="table_layout_9_toggle_shrink">Toggle Shrink</string>
+    <string name="table_layout_10_user">User</string>
+    <string name="table_layout_10_password">Password</string>
+    <string name="table_layout_10_cancel">Cancel</string>
+    <string name="table_layout_10_login">Login</string>
+    <string name="table_layout_12_a">A</string>
+    <string name="table_layout_12_b">BB</string>
+    <string name="table_layout_12_c">CCCC</string>
+    <string name="table_layout_12_d">D</string>
+    <string name="table_layout_12_e">E</string>
+    <string name="table_layout_12_f">F</string>
+    <string name="table_layout_12_g">G</string>
+    <string name="table_layout_12_h">H</string>
+    <string name="visibility_1_view_1">View A</string>
+    <string name="visibility_1_view_2">View B</string>
+    <string name="visibility_1_view_3">View C</string>
+    <string name="visibility_1_vis">Vis</string>
+    <string name="visibility_1_invis">Invis</string>
+    <string name="visibility_1_gone">Gone</string>
+
+
+    <string name="google_login_username_text"></string>
+
+    <string name="incoming_message_notify_text">Show Notification</string>
+
+    <string name="incoming_message_info_message_text">this is the text of a previous message.\nkthx. meet u for dinner. cul8r</string>
+
+    <string name="incoming_message_view_message_text">this is the text of a previous message.\nkthx. meet u for dinner. cul8r</string>
+    <string name="imcoming_message_view_message2_text">Did you notice that the status bar icon disappeared?</string>
+    <string name="imcoming_message_ticker_text">New text message: <xliff:g id="text">%0$s</xliff:g></string>
+
+    <string name="log_text_box_1_do_nothing_text">Do nothing</string>
+    <string name="log_text_box_1_add_text">Add</string>
+
+    <string name="notify_with_text_long_notify_text">Show Long Notification</string>
+    <string name="notify_with_text_short_notify_text">Show Short Notification</string>
+
+    <string name="marquee_default">This use the default marquee animation limit of 3</string>
+    <string name="marquee_once">This will run the marquee animation once</string>
+    <string name="marquee_forever">This will run the marquee animation forever</string>
+
+    <string name="table_layout_10_password_text"></string>
+    <string name="table_layout_10_username_text"></string>
+
+    <string name="text_switcher_1_next_text">Next</string>
+
+    <string name="date_widgets_example_dateDisplay_text"></string>
+    <string name="date_widgets_example_pickTime_text">change the time</string>
+    <string name="date_widgets_example_pickDate_text">change the date</string>
+
+    <string name="buttons_1_normal">Normal</string>
+    <string name="buttons_1_right">Right</string>
+    <string name="buttons_1_small">Small</string>
+    <string name="buttons_1_small_right">S R</string>
+    <string name="buttons_1_small_left">S L</string>
+    <string name="buttons_1_small_up">S U</string>
+    <string name="buttons_1_small_down">S D</string>
+    <string name="buttons_1_toggle">Toggle</string>
+
+    <string name="expandable_list_sample_action">Sample action</string>
+
+    <string name="chronometer_start">Start</string>
+    <string name="chronometer_stop">Stop</string>
+    <string name="chronometer_reset">Reset</string>
+    <string name="chronometer_set_format">Set format string</string>
+    <string name="chronometer_clear_format">Clear format string</string>
+    <string name="chronometer_initial_format">Initial format: <xliff:g id="initial-format">%s</xliff:g></string>
+
+    <!-- ============================ -->
+    <!--  vibrator examples strings  -->
+    <!-- ============================ -->
+
+    <string name="vibrate">Vibrate</string>
+
+
+    <string name="image_view_large_normal">Large image at normal size</string>
+    <string name="image_view_large_at_most">Large image scaled to at most 50x50</string>
+    <string name="image_view_large_at_most_padded">Large image scaled to at most 70x70 with padding</string>
+    <string name="image_view_large_exactly_padded">Large image scaled to exactly 70x70 with padding</string>
+    <string name="image_view_small_normal">Small image at normal size</string>
+    <string name="image_view_small_at_most">Small image scaled to at most 50x50</string>
+    <string name="image_view_small_at_most_padded">Small image scaled to at most 70x70 with padding</string>
+    <string name="image_view_small_exactly_padded">Small image scaled to exactly 70x70 with padding</string>
+
+    <!-- Shouldn't be localized -->
+    <string name="textColorPrimary">textColorPrimary</string>
+    <string name="textColorSecondary">textColorSecondary</string>
+    <string name="textColorTertiary">textColorTertiary</string>
+    <string name="listSeparatorTextViewStyle">listSeparatorTextViewStyle</string>
+
+    <!-- ============================ -->
+    <!--  gadget examples strings     -->
+    <!-- ============================ -->
+
+    <string name="gadget_configure_instructions">This text will be shown before the date in our example gadget.</string>
+    <string name="gadget_prefix_default">Oh hai</string>
+    <string name="gadget_text_format"><xliff:g id="prefix">%1$s</xliff:g>: <xliff:g id="time">%2$s</xliff:g></string>
+</resources>
+
diff --git a/samples/ApiDemos/res/values/styles.xml b/samples/ApiDemos/res/values/styles.xml
new file mode 100644
index 0000000..40e934e
--- /dev/null
+++ b/samples/ApiDemos/res/values/styles.xml
@@ -0,0 +1,66 @@
+<?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>
+    <!-- Base application theme is the default theme. -->
+    <style name="Theme" parent="android:Theme">
+    </style>
+
+    <!-- Variation on our application theme that forces a plain
+        text style. -->
+    <style name="Theme.PlainText">
+        <item name="android:textAppearance">@style/TextAppearance.Theme.PlainText</item>
+    </style>
+
+    <!-- Variation on our application theme that has a black
+         background. -->
+    <style name="Theme.Black">
+        <item name="android:windowBackground">@drawable/screen_background_black</item>
+    </style>
+
+    <!-- A theme for a custom dialog appearance.  Here we use an ugly
+         custom frame. -->
+    <style name="Theme.CustomDialog" parent="android:style/Theme.Dialog">
+        <item name="android:windowBackground">@drawable/filled_box</item>
+    </style>
+
+    <!-- A theme that has a translucent background.  Here we explicitly specify
+         that this theme is to inherit from the system's translucent theme,
+         which sets up various attributes correctly.. -->
+    <style name="Theme.Translucent" parent="android:style/Theme.Translucent">
+        <item name="android:windowBackground">@drawable/translucent_background</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:colorForeground">#fff</item>
+    </style>
+
+    <!-- Variation on our application theme that has a transparent
+         background; this example completely removes the background,
+         allowing the activity to decide how to composite.  Also here we
+         force the translucency ourself rather than making use of the built-in
+         translucent theme. -->
+    <style name="Theme.Transparent">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
+        <item name="android:windowBackground">@drawable/transparent_background</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:colorForeground">#fff</item>
+    </style>
+    
+    <style name="TextAppearance.Theme.PlainText" parent="android:TextAppearance.Theme">
+        <item name="android:textStyle">normal</item>
+    </style>
+
+</resources>
diff --git a/samples/ApiDemos/res/xml/advanced_preferences.xml b/samples/ApiDemos/res/xml/advanced_preferences.xml
new file mode 100644
index 0000000..c362297
--- /dev/null
+++ b/samples/ApiDemos/res/xml/advanced_preferences.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This is an advanced example showing the custom preference types and manually handling
+     preference clicks. -->
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- My custom preference type.  This just replaces the actual widget
+         portion of the preference, if the whole preference wanted to be
+         replaced we would use the layout attribute instead of the widgetLayout
+         attribute. -->
+    <com.example.android.apis.app.MyPreference
+            android:key="my_preference"
+            android:title="@string/title_my_preference"
+            android:summary="@string/summary_my_preference"
+            android:defaultValue="100" />
+
+    <CheckBoxPreference
+            android:key="advanced_checkbox_preference"
+            android:title="@string/title_advanced_toggle_preference"
+            android:summaryOn="@string/summary_on_advanced_toggle_preference" 
+            android:summaryOff="@string/summary_off_advanced_toggle_preference" />
+
+</PreferenceScreen>
diff --git a/samples/ApiDemos/res/xml/default_values.xml b/samples/ApiDemos/res/xml/default_values.xml
new file mode 100644
index 0000000..da15a62
--- /dev/null
+++ b/samples/ApiDemos/res/xml/default_values.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This is a primitive example showing how to set default values for preferences.
+     See DefaultValues.java for more information. -->
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <CheckBoxPreference
+            android:key="default_toggle"
+            android:defaultValue="true"
+            android:title="@string/title_checkbox_preference"
+            android:summary="@string/summary_checkbox_preference" />
+
+    <EditTextPreference
+            android:key="default_edittext"
+            android:defaultValue="@string/default_value_edittext_preference"
+            android:title="@string/title_edittext_preference"
+            android:summary="@string/summary_edittext_preference"
+            android:dialogTitle="@string/dialog_title_edittext_preference" />
+            
+    <ListPreference
+            android:key="default_list"
+            android:defaultValue="@string/default_value_list_preference"
+            android:title="@string/title_list_preference"
+            android:summary="@string/summary_list_preference"
+            android:entries="@array/entries_list_preference"
+            android:entryValues="@array/entryvalues_list_preference"
+            android:dialogTitle="@string/dialog_title_list_preference" />
+
+</PreferenceScreen>
diff --git a/samples/ApiDemos/res/xml/gadget_provider.xml b/samples/ApiDemos/res/xml/gadget_provider.xml
new file mode 100644
index 0000000..9ad6845
--- /dev/null
+++ b/samples/ApiDemos/res/xml/gadget_provider.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="60dp"
+    android:minHeight="30dp"
+    android:updatePeriodMillis="86400000"
+    android:initialLayout="@layout/gadget_provider"
+    android:configure="com.example.android.apis.gadget.ExampleGadgetConfigure"
+    >
+</gadget-provider>
+
+<!-- 86400000 is the value of AlarmManager.INTERVAL_DAY - or once per day. -->
+
diff --git a/samples/ApiDemos/res/xml/preference_dependencies.xml b/samples/ApiDemos/res/xml/preference_dependencies.xml
new file mode 100644
index 0000000..5eae580
--- /dev/null
+++ b/samples/ApiDemos/res/xml/preference_dependencies.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This is a primitive example showing how some preferences can depend on other preferences. -->
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+            android:title="@string/example_preference_dependency">
+            
+        <CheckBoxPreference
+                android:key="wifi"
+                android:title="@string/title_wifi" />
+            
+        <EditTextPreference
+                android:layout="?android:attr/preferenceLayoutChild"
+                android:title="@string/title_wifi_settings"
+                android:dependency="wifi" />
+            
+    </PreferenceCategory>
+                
+</PreferenceScreen>
diff --git a/samples/ApiDemos/res/xml/preferences.xml b/samples/ApiDemos/res/xml/preferences.xml
new file mode 100644
index 0000000..59b23f1
--- /dev/null
+++ b/samples/ApiDemos/res/xml/preferences.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This is a primitive example showing the different types of preferences available. -->
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+            android:title="@string/inline_preferences">
+            
+        <CheckBoxPreference
+                android:key="checkbox_preference"
+                android:title="@string/title_toggle_preference"
+                android:summary="@string/summary_toggle_preference" />
+            
+    </PreferenceCategory>
+                
+    <PreferenceCategory
+            android:title="@string/dialog_based_preferences">
+
+        <EditTextPreference
+                android:key="edittext_preference"
+                android:title="@string/title_edittext_preference"
+                android:summary="@string/summary_edittext_preference"
+                android:dialogTitle="@string/dialog_title_edittext_preference" />
+                
+        <ListPreference
+                android:key="list_preference"
+                android:title="@string/title_list_preference"
+                android:summary="@string/summary_list_preference"
+                android:entries="@array/entries_list_preference"
+                android:entryValues="@array/entryvalues_list_preference"
+                android:dialogTitle="@string/dialog_title_list_preference" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/launch_preferences">
+
+        <!-- This PreferenceScreen tag serves as a screen break (similar to page break
+             in word processing). Like for other preference types, we assign a key
+             here so it is able to save and restore its instance state. -->
+        <PreferenceScreen
+                android:key="screen_preference"
+                android:title="@string/title_screen_preference"
+                android:summary="@string/summary_screen_preference">
+            
+            <!-- You can place more preferences here that will be shown on the next screen. -->
+                     
+            <CheckBoxPreference
+                    android:key="next_screen_checkbox_preference"
+                    android:title="@string/title_next_screen_toggle_preference"
+                    android:summary="@string/summary_next_screen_toggle_preference" />
+                
+        </PreferenceScreen>
+
+        <PreferenceScreen
+                android:title="@string/title_intent_preference"
+                android:summary="@string/summary_intent_preference">
+
+            <intent android:action="android.intent.action.VIEW"
+                    android:data="http://www.android.com" />
+
+        </PreferenceScreen>
+
+    </PreferenceCategory>
+    
+    <PreferenceCategory
+            android:title="@string/preference_attributes">
+    
+        <CheckBoxPreference
+                android:key="parent_checkbox_preference"
+                android:title="@string/title_parent_preference"
+                android:summary="@string/summary_parent_preference" />
+
+        <!-- The visual style of a child is defined by this styled theme attribute. -->
+        <CheckBoxPreference
+                android:key="child_checkbox_preference"
+                android:dependency="parent_checkbox_preference"
+                android:layout="?android:attr/preferenceLayoutChild"
+                android:title="@string/title_child_preference"
+                android:summary="@string/summary_child_preference" />
+            
+    </PreferenceCategory>
+    
+</PreferenceScreen>
diff --git a/samples/ApiDemos/res/xml/searchable.xml b/samples/ApiDemos/res/xml/searchable.xml
new file mode 100644
index 0000000..df4ef7a
--- /dev/null
+++ b/samples/ApiDemos/res/xml/searchable.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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 configuration information -->
+<!-- for the Search Manager. -->
+
+<searchable xmlns:android="http://schemas.android.com/apk/res/android"
+    android:label="@string/search_label"
+    android:hint="@string/search_hint" 
+    android:searchMode="showSearchLabelAsBadge"
+    
+    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
+    android:voiceLanguageModel="free_form"
+    android:voicePromptText="@string/search_invoke"
+
+    android:searchSuggestAuthority="com.example.android.apis.SuggestionProvider"
+    android:searchSuggestSelection=" ? "
+/>
diff --git a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
new file mode 100644
index 0000000..78b1fd7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ApiDemos extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        Intent intent = getIntent();
+        String path = intent.getStringExtra("com.example.android.apis.Path");
+        
+        if (path == null) {
+            path = "";
+        }
+
+        setListAdapter(new SimpleAdapter(this, getData(path),
+                android.R.layout.simple_list_item_1, new String[] { "title" },
+                new int[] { android.R.id.text1 }));
+        getListView().setTextFilterEnabled(true);
+    }
+
+    protected List getData(String prefix) {
+        List<Map> myData = new ArrayList<Map>();
+
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
+
+        PackageManager pm = getPackageManager();
+        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
+
+        if (null == list)
+            return myData;
+
+        String[] prefixPath;
+        
+        if (prefix.equals("")) {
+            prefixPath = null;
+        } else {
+            prefixPath = prefix.split("/");
+        }
+        
+        int len = list.size();
+        
+        Map<String, Boolean> entries = new HashMap<String, Boolean>();
+
+        for (int i = 0; i < len; i++) {
+            ResolveInfo info = list.get(i);
+            CharSequence labelSeq = info.loadLabel(pm);
+            String label = labelSeq != null
+                    ? labelSeq.toString()
+                    : info.activityInfo.name;
+            
+            if (prefix.length() == 0 || label.startsWith(prefix)) {
+                
+                String[] labelPath = label.split("/");
+
+                String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
+
+                if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
+                    addItem(myData, nextLabel, activityIntent(
+                            info.activityInfo.applicationInfo.packageName,
+                            info.activityInfo.name));
+                } else {
+                    if (entries.get(nextLabel) == null) {
+                        addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
+                        entries.put(nextLabel, true);
+                    }
+                }
+            }
+        }
+
+        Collections.sort(myData, sDisplayNameComparator);
+        
+        return myData;
+    }
+
+    private final static Comparator<Map> sDisplayNameComparator = new Comparator<Map>() {
+        private final Collator   collator = Collator.getInstance();
+
+        public int compare(Map map1, Map map2) {
+            return collator.compare(map1.get("title"), map2.get("title"));
+        }
+    };
+
+    protected Intent activityIntent(String pkg, String componentName) {
+        Intent result = new Intent();
+        result.setClassName(pkg, componentName);
+        return result;
+    }
+    
+    protected Intent browseIntent(String path) {
+        Intent result = new Intent();
+        result.setClass(this, ApiDemos.class);
+        result.putExtra("com.example.android.apis.Path", path);
+        return result;
+    }
+
+    protected void addItem(List<Map> data, String name, Intent intent) {
+        Map<String, Object> temp = new HashMap<String, Object>();
+        temp.put("title", name);
+        temp.put("intent", intent);
+        data.add(temp);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Map map = (Map) l.getItemAtPosition(position);
+
+        Intent intent = (Intent) map.get("intent");
+        startActivity(intent);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/ApiDemosApplication.java b/samples/ApiDemos/src/com/example/android/apis/ApiDemosApplication.java
new file mode 100644
index 0000000..92460e5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/ApiDemosApplication.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis;
+
+import com.example.android.apis.app.DefaultValues;
+
+import android.app.Application;
+import android.preference.PreferenceManager;
+
+/**
+ * This is an example of a {@link android.app.Application} class.  Ordinarily you would use
+ * a class like this as a central repository for information that might be shared between multiple
+ * activities.
+ * 
+ * In this case, we have not defined any specific work for this Application.
+ * 
+ * See samples/ApiDemos/tests/src/com.example.android.apis/ApiDemosApplicationTests for an example
+ * of how to perform unit tests on an Application object.
+ */
+public class ApiDemosApplication extends Application {
+
+    public void onCreate() {
+        /*
+         * This populates the default values from the preferences XML file. See
+         * {@link DefaultValues} for more details.
+         */
+        PreferenceManager.setDefaultValues(this, R.xml.default_values, false);
+    }
+
+    public void onTerminate() {
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/_package.html b/samples/ApiDemos/src/com/example/android/apis/_package.html
new file mode 100644
index 0000000..307c136
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/_package.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="assets/style.css" />
+<script type="text/javascript" src="http://www.corp.google.com/style/prettify.js"></script>
+<script src="http://www.corp.google.com/eng/techpubs/include/navbar.js" type="text/javascript"></script>
+
+
+
+</head>
+
+<body>
+
+<p>
+Examples of how to use the android platform APIs.  See:
+
+<ol>
+	<li> <a href="com.android.sdk.app">sdk.app</a> for examples
+		of using the android.app APIs.
+	<li> <a href="com.android.sdk.view">sdk.view</a> for examples
+		of using the android.view APIs.
+</ol>
+</p>
+
+
+</body>
+</html>
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.java b/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.java
new file mode 100644
index 0000000..61ee828
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.animation;
+
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+import android.graphics.Camera;
+import android.graphics.Matrix;
+
+/**
+ * An animation that rotates the view on the Y axis between two specified angles.
+ * This animation also adds a translation on the Z axis (depth) to improve the effect.
+ */
+public class Rotate3dAnimation extends Animation {
+    private final float mFromDegrees;
+    private final float mToDegrees;
+    private final float mCenterX;
+    private final float mCenterY;
+    private final float mDepthZ;
+    private final boolean mReverse;
+    private Camera mCamera;
+
+    /**
+     * Creates a new 3D rotation on the Y axis. The rotation is defined by its
+     * start angle and its end angle. Both angles are in degrees. The rotation
+     * is performed around a center point on the 2D space, definied by a pair
+     * of X and Y coordinates, called centerX and centerY. When the animation
+     * starts, a translation on the Z axis (depth) is performed. The length
+     * of the translation can be specified, as well as whether the translation
+     * should be reversed in time.
+     *
+     * @param fromDegrees the start angle of the 3D rotation
+     * @param toDegrees the end angle of the 3D rotation
+     * @param centerX the X center of the 3D rotation
+     * @param centerY the Y center of the 3D rotation
+     * @param reverse true if the translation should be reversed, false otherwise
+     */
+    public Rotate3dAnimation(float fromDegrees, float toDegrees,
+            float centerX, float centerY, float depthZ, boolean reverse) {
+        mFromDegrees = fromDegrees;
+        mToDegrees = toDegrees;
+        mCenterX = centerX;
+        mCenterY = centerY;
+        mDepthZ = depthZ;
+        mReverse = reverse;
+    }
+
+    @Override
+    public void initialize(int width, int height, int parentWidth, int parentHeight) {
+        super.initialize(width, height, parentWidth, parentHeight);
+        mCamera = new Camera();
+    }
+
+    @Override
+    protected void applyTransformation(float interpolatedTime, Transformation t) {
+        final float fromDegrees = mFromDegrees;
+        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
+
+        final float centerX = mCenterX;
+        final float centerY = mCenterY;
+        final Camera camera = mCamera;
+
+        final Matrix matrix = t.getMatrix();
+
+        camera.save();
+        if (mReverse) {
+            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
+        } else {
+            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
+        }
+        camera.rotateY(degrees);
+        camera.getMatrix(matrix);
+        camera.restore();
+
+        matrix.preTranslate(-centerX, -centerY);
+        matrix.postTranslate(centerX, centerY);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/Transition3d.java b/samples/ApiDemos/src/com/example/android/apis/animation/Transition3d.java
new file mode 100644
index 0000000..38e69d0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/Transition3d.java
@@ -0,0 +1,175 @@
+package com.example.android.apis.animation;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ListView;
+import android.widget.ArrayAdapter;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ * This sample application shows how to use layout animation and various
+ * transformations on views. The result is a 3D transition between a
+ * ListView and an ImageView. When the user clicks the list, it flips to
+ * show the picture. When the user clicks the picture, it flips to show the
+ * list. The animation is made of two smaller animations: the first half
+ * rotates the list by 90 degrees on the Y axis and the second half rotates
+ * the picture by 90 degrees on the Y axis. When the first half finishes, the
+ * list is made invisible and the picture is set visible.
+ */
+public class Transition3d extends Activity implements
+        AdapterView.OnItemClickListener, View.OnClickListener {
+    private ListView mPhotosList;
+    private ViewGroup mContainer;
+    private ImageView mImageView;
+
+    // Names of the photos we show in the list
+    private static final String[] PHOTOS_NAMES = new String[] {
+            "Lyon",
+            "Livermore",
+            "Tahoe Pier",
+            "Lake Tahoe",
+            "Grand Canyon",
+            "Bodie"
+    };
+
+    // Resource identifiers for the photos we want to display
+    private static final int[] PHOTOS_RESOURCES = new int[] {
+            R.drawable.photo1,
+            R.drawable.photo2,
+            R.drawable.photo3,
+            R.drawable.photo4,
+            R.drawable.photo5,
+            R.drawable.photo6
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.animations_main_screen);
+
+        mPhotosList = (ListView) findViewById(android.R.id.list);
+        mImageView = (ImageView) findViewById(R.id.picture);
+        mContainer = (ViewGroup) findViewById(R.id.container);
+
+        // Prepare the ListView
+        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, PHOTOS_NAMES);
+
+        mPhotosList.setAdapter(adapter);
+        mPhotosList.setOnItemClickListener(this);
+
+        // Prepare the ImageView
+        mImageView.setClickable(true);
+        mImageView.setFocusable(true);
+        mImageView.setOnClickListener(this);
+
+        // Since we are caching large views, we want to keep their cache
+        // between each animation
+        mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);
+    }
+
+    /**
+     * Setup a new 3D rotation on the container view.
+     *
+     * @param position the item that was clicked to show a picture, or -1 to show the list
+     * @param start the start angle at which the rotation must begin
+     * @param end the end angle of the rotation
+     */
+    private void applyRotation(int position, float start, float end) {
+        // Find the center of the container
+        final float centerX = mContainer.getWidth() / 2.0f;
+        final float centerY = mContainer.getHeight() / 2.0f;
+
+        // Create a new 3D rotation with the supplied parameter
+        // The animation listener is used to trigger the next animation
+        final Rotate3dAnimation rotation =
+                new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
+        rotation.setDuration(500);
+        rotation.setFillAfter(true);
+        rotation.setInterpolator(new AccelerateInterpolator());
+        rotation.setAnimationListener(new DisplayNextView(position));
+
+        mContainer.startAnimation(rotation);
+    }
+
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        // Pre-load the image then start the animation
+        mImageView.setImageResource(PHOTOS_RESOURCES[position]);
+        applyRotation(position, 0, 90);
+    }
+
+    public void onClick(View v) {
+        applyRotation(-1, 180, 90);
+    }
+
+    /**
+     * This class listens for the end of the first half of the animation.
+     * It then posts a new action that effectively swaps the views when the container
+     * is rotated 90 degrees and thus invisible.
+     */
+    private final class DisplayNextView implements Animation.AnimationListener {
+        private final int mPosition;
+
+        private DisplayNextView(int position) {
+            mPosition = position;
+        }
+
+        public void onAnimationStart(Animation animation) {
+        }
+
+        public void onAnimationEnd(Animation animation) {
+            mContainer.post(new SwapViews(mPosition));
+        }
+
+        public void onAnimationRepeat(Animation animation) {
+        }
+    }
+
+    /**
+     * This class is responsible for swapping the views and start the second
+     * half of the animation.
+     */
+    private final class SwapViews implements Runnable {
+        private final int mPosition;
+
+        public SwapViews(int position) {
+            mPosition = position;
+        }
+
+        public void run() {
+            final float centerX = mContainer.getWidth() / 2.0f;
+            final float centerY = mContainer.getHeight() / 2.0f;
+            Rotate3dAnimation rotation;
+            
+            if (mPosition > -1) {
+                mPhotosList.setVisibility(View.GONE);
+                mImageView.setVisibility(View.VISIBLE);
+                mImageView.requestFocus();
+
+                rotation = new Rotate3dAnimation(90, 180, centerX, centerY, 310.0f, false);
+            } else {
+                mImageView.setVisibility(View.GONE);
+                mPhotosList.setVisibility(View.VISIBLE);
+                mPhotosList.requestFocus();
+
+                rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false);
+            }
+
+            rotation.setDuration(500);
+            rotation.setFillAfter(true);
+            rotation.setInterpolator(new DecelerateInterpolator());
+
+            mContainer.startAnimation(rotation);
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/_index.html b/samples/ApiDemos/src/com/example/android/apis/animation/_index.html
new file mode 100644
index 0000000..cd2ea53
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/_index.html
@@ -0,0 +1,48 @@
+
+<h3>Drawable</h3>
+<dl>
+  <dt><a href="ShapeDrawable1.html">ShapeDrawable</a></dt>
+  <dd>Demonstrates creating Drawables in XML.</dd>
+</dl>
+
+<h3>OpenGL|ES</h3>
+<dl>
+  <dt><a href="CameraPreview.html">CameraPreview</a></dt>
+  <dd> Demonstrates capturing the image stream from the camera, drawing to a surface (extending SurfaceView) on a separate thread (extending Thread).</dd>
+
+  <dt><a href="GLSurfaceViewActivity.html">GL SurfaceView</a></dt>
+  <dd>Demonstrates how to perform OpenGL rendering in to a SurfaceView.
+  <dl>
+  <dt>Code:
+  <dd> <a href="GLSurfaceViewActivity.html">GLSurfaceViewActivity.java</a>,
+    <a href="GLSurfaceView.html">GLSurfaceView.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/hello_world.html">
+  hello_world.xml</a>
+  </dl>
+  </dd>
+
+  <dt><a href="PolyToPoly.html">PolyToPoly</a></dt>
+  <dd>Demonstrates calling the <a href="@{docRoot}reference/android/graphics/Matrix.html#setPolyToPoly(float[],%20int,%20float[],%20int,%20int)">Matrix.setPolyToPoly()</a> method to translate coordinates on a canvas to a new perspective (used to simulate perspective). </dd>
+
+  <dt><a href="DrawPoints.html">DrawPoints</a></dt>
+  <dd>Demonstrates using the <a href="android.graphics.Paint">Paint</a> and <a href="android.graphics.Canvas">Canvas</a> objects to draw random points on the screen, with different colors and strokes. </dd>
+
+  <dt><a href="PathEffects.html">PathEffects</a></dt>
+  <dd> Demonstrates the use of <a href="android.graphics.Path">Path</a> and various <a href="android.graphics.PathEffect">PathEffect</a> subclasses. </dd>
+
+  <dt><a href="SurfaceViewOverlay.html">SurfaceView Overlay</a></dt>
+  <dd>Shows how you can place overlays on top of a SurfaceView.
+  <dl>
+  <dt>Code:
+  <dd> <a href="SurfaceViewOverlay.html">SurfaceViewOverlay.java</a>,
+    <a href="GLSurfaceView.html">GLSurfaceView.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/surface_view_overlay.html">
+  surface_view_overlay.xml</a>
+  </dl>
+  </dd>
+
+  <dt><a href="TouchPaint.html">TouchPaint</a></dt>
+  <dd> Demonstrates the handling of touch screen events to implement a simple painting app. </dd>
+</dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java b/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java
new file mode 100644
index 0000000..2dbbc45
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AdvancedPreferences.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceActivity;
+import android.preference.CheckBoxPreference;
+import android.widget.Toast;
+
+/**
+ * Example that shows finding a preference from the hierarchy and a custom preference type.
+ */
+public class AdvancedPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
+    public static final String KEY_MY_PREFERENCE = "my_preference";
+    public static final String KEY_ADVANCED_CHECKBOX_PREFERENCE = "advanced_checkbox_preference";
+
+    private CheckBoxPreference mCheckBoxPreference;
+    private Handler mHandler = new Handler();
+    
+    /**
+     * This is a simple example of controlling a preference from code.
+     */
+    private Runnable mForceCheckBoxRunnable = new Runnable() {
+        public void run() {
+            if (mCheckBoxPreference != null) {
+                mCheckBoxPreference.setChecked(!mCheckBoxPreference.isChecked());
+            }
+            
+            // Force toggle again in a second
+            mHandler.postDelayed(this, 1000);
+        }
+    };
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Load the XML preferences file
+        addPreferencesFromResource(R.xml.advanced_preferences);
+        
+        // Get a reference to the checkbox preference
+        mCheckBoxPreference = (CheckBoxPreference)getPreferenceScreen().findPreference(
+                KEY_ADVANCED_CHECKBOX_PREFERENCE);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Start the force toggle
+        mForceCheckBoxRunnable.run();
+        
+        // Set up a listener whenever a key changes
+        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // Unregister the listener whenever a key changes
+        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+        
+        mHandler.removeCallbacks(mForceCheckBoxRunnable);
+    }
+
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        // Let's do something when my counter preference value changes
+        if (key.equals(KEY_MY_PREFERENCE)) {
+            Toast.makeText(this, "Thanks! You increased my count to "
+                    + sharedPreferences.getInt(key, 0), Toast.LENGTH_SHORT).show();
+        }
+    }
+    
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlarmController.java b/samples/ApiDemos/src/com/example/android/apis/app/AlarmController.java
new file mode 100644
index 0000000..2ba5735
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlarmController.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+import java.util.Calendar;
+
+/**
+ * Example of scheduling one-shot and repeating alarms.  See
+ * {@link OneShotAlarm} for the code run when the one-shot alarm goes off, and
+ * {@link RepeatingAlarm} for the code run when the repeating alarm goes off.
+ * <h4>Demo</h4>
+App/Service/Alarm Controller
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/AlarmController.java</td>
+            <td class="DescrColumn">The activity that lets you schedule alarms</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/OneShotAlarm.java</td>
+            <td class="DescrColumn">This is an intent receiver that executes when the
+                one-shot alarm goes off</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/RepeatingAlarm.java</td>
+            <td class="DescrColumn">This is an intent receiver that executes when the
+                repeating alarm goes off</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">/res/any/layout/alarm_controller.xml</td>
+            <td class="DescrColumn">Defines contents of the screen</td>
+        </tr>
+</table>
+
+ */
+public class AlarmController extends Activity {
+    Toast mToast;
+
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.alarm_controller);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.one_shot);
+        button.setOnClickListener(mOneShotListener);
+        button = (Button)findViewById(R.id.start_repeating);
+        button.setOnClickListener(mStartRepeatingListener);
+        button = (Button)findViewById(R.id.stop_repeating);
+        button.setOnClickListener(mStopRepeatingListener);
+    }
+
+    private OnClickListener mOneShotListener = new OnClickListener() {
+        public void onClick(View v) {
+            // When the alarm goes off, we want to broadcast an Intent to our
+            // BroadcastReceiver.  Here we make an Intent with an explicit class
+            // name to have our own receiver (which has been published in
+            // AndroidManifest.xml) instantiated and called, and then create an
+            // IntentSender to have the intent executed as a broadcast.
+            Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
+            PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,
+                    0, intent, 0);
+
+            // We want the alarm to go off 30 seconds from now.
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTimeInMillis(System.currentTimeMillis());
+            calendar.add(Calendar.SECOND, 30);
+
+            // Schedule the alarm!
+            AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
+            am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
+
+            // Tell the user about what we did.
+            if (mToast != null) {
+                mToast.cancel();
+            }
+            mToast = Toast.makeText(AlarmController.this, R.string.one_shot_scheduled,
+                    Toast.LENGTH_LONG);
+            mToast.show();
+        }
+    };
+
+    private OnClickListener mStartRepeatingListener = new OnClickListener() {
+        public void onClick(View v) {
+            // When the alarm goes off, we want to broadcast an Intent to our
+            // BroadcastReceiver.  Here we make an Intent with an explicit class
+            // name to have our own receiver (which has been published in
+            // AndroidManifest.xml) instantiated and called, and then create an
+            // IntentSender to have the intent executed as a broadcast.
+            // Note that unlike above, this IntentSender is configured to
+            // allow itself to be sent multiple times.
+            Intent intent = new Intent(AlarmController.this, RepeatingAlarm.class);
+            PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,
+                    0, intent, 0);
+            
+            // We want the alarm to go off 30 seconds from now.
+            long firstTime = SystemClock.elapsedRealtime();
+            firstTime += 15*1000;
+
+            // Schedule the alarm!
+            AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
+            am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                            firstTime, 15*1000, sender);
+
+            // Tell the user about what we did.
+            if (mToast != null) {
+                mToast.cancel();
+            }
+            mToast = Toast.makeText(AlarmController.this, R.string.repeating_scheduled,
+                    Toast.LENGTH_LONG);
+            mToast.show();
+        }
+    };
+
+    private OnClickListener mStopRepeatingListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Create the same intent, and thus a matching IntentSender, for
+            // the one that was scheduled.
+            Intent intent = new Intent(AlarmController.this, RepeatingAlarm.class);
+            PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,
+                    0, intent, 0);
+            
+            // And cancel the alarm.
+            AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
+            am.cancel(sender);
+
+            // Tell the user about what we did.
+            if (mToast != null) {
+                mToast.cancel();
+            }
+            mToast = Toast.makeText(AlarmController.this, R.string.repeating_unscheduled,
+                    Toast.LENGTH_LONG);
+            mToast.show();
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlarmService.java b/samples/ApiDemos/src/com/example/android/apis/app/AlarmService.java
new file mode 100644
index 0000000..151838a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlarmService.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+
+/**
+ * This demonstrates how you can schedule an alarm that causes a service to
+ * be started.  This is useful when you want to schedule alarms that initiate
+ * long-running operations, such as retrieving recent e-mails.
+ */
+public class AlarmService extends Activity {
+    private PendingIntent mAlarmSender;
+    
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create an IntentSender that will launch our service, to be scheduled
+        // with the alarm manager.
+        mAlarmSender = PendingIntent.getService(AlarmService.this,
+                0, new Intent(AlarmService.this, AlarmService_Service.class), 0);
+        
+        setContentView(R.layout.alarm_service);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.start_alarm);
+        button.setOnClickListener(mStartAlarmListener);
+        button = (Button)findViewById(R.id.stop_alarm);
+        button.setOnClickListener(mStopAlarmListener);
+    }
+
+    private OnClickListener mStartAlarmListener = new OnClickListener() {
+        public void onClick(View v) {
+            // We want the alarm to go off 30 seconds from now.
+            long firstTime = SystemClock.elapsedRealtime();
+
+            // Schedule the alarm!
+            AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
+            am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                            firstTime, 30*1000, mAlarmSender);
+
+            // Tell the user about what we did.
+            Toast.makeText(AlarmService.this, R.string.repeating_scheduled,
+                    Toast.LENGTH_LONG).show();
+        }
+    };
+
+    private OnClickListener mStopAlarmListener = new OnClickListener() {
+        public void onClick(View v) {
+            // And cancel the alarm.
+            AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
+            am.cancel(mAlarmSender);
+
+            // Tell the user about what we did.
+            Toast.makeText(AlarmService.this, R.string.repeating_unscheduled,
+                    Toast.LENGTH_LONG).show();
+
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java b/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java
new file mode 100644
index 0000000..6762ba9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.widget.Toast;
+
+/**
+ * This is an example of implementing an application service that will run in
+ * response to an alarm, allowing us to move long duration work out of an
+ * intent receiver.
+ * 
+ * @see AlarmService
+ * @see AlarmService_Alarm
+ */
+public class AlarmService_Service extends Service {
+    NotificationManager mNM;
+
+    @Override
+    public void onCreate() {
+        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // show the icon in the status bar
+        showNotification();
+
+        // Start up the thread running the service.  Note that we create a
+        // separate thread because the service normally runs in the process's
+        // main thread, which we don't want to block.
+        Thread thr = new Thread(null, mTask, "AlarmService_Service");
+        thr.start();
+    }
+
+    @Override
+    public void onDestroy() {
+        // Cancel the notification -- we use the same ID that we had used to start it
+        mNM.cancel(R.string.alarm_service_started);
+
+        // Tell the user we stopped.
+        Toast.makeText(this, R.string.alarm_service_finished, Toast.LENGTH_SHORT).show();
+    }
+
+    /**
+     * The function that runs in our worker thread
+     */
+    Runnable mTask = new Runnable() {
+        public void run() {
+            // Normally we would do some work here...  for our sample, we will
+            // just sleep for 30 seconds.
+            long endTime = System.currentTimeMillis() + 15*1000;
+            while (System.currentTimeMillis() < endTime) {
+                synchronized (mBinder) {
+                    try {
+                        mBinder.wait(endTime - System.currentTimeMillis());
+                    } catch (Exception e) {
+                    }
+                }
+            }
+
+            // Done with our work...  stop the service!
+            AlarmService_Service.this.stopSelf();
+        }
+    };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    /**
+     * Show a notification while this service is running.
+     */
+    private void showNotification() {
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(R.string.alarm_service_started);
+
+        // Set the icon, scrolling text and timestamp
+        Notification notification = new Notification(R.drawable.stat_sample, text,
+                System.currentTimeMillis());
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, AlarmService.class), 0);
+
+        // Set the info for the views that show in the notification panel.
+        notification.setLatestEventInfo(this, getText(R.string.alarm_service_label),
+                       text, contentIntent);
+
+        // Send the notification.
+        // We use a layout id because it is a unique number.  We use it later to cancel.
+        mNM.notify(R.string.alarm_service_started, notification);
+    }
+
+    /**
+     * This is the object that receives interactions from clients.  See RemoteService
+     * for a more complete example.
+     */
+    private final IBinder mBinder = new Binder() {
+        @Override
+		protected boolean onTransact(int code, Parcel data, Parcel reply,
+		        int flags) throws RemoteException {
+            return super.onTransact(code, data, reply, flags);
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
new file mode 100644
index 0000000..fabdfc1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.example.android.apis.R;
+
+/**
+ * Example of how to use an {@link android.app.AlertDialog}.
+ * <h3>AlertDialogSamples</h3>
+
+<p>This demonstrates the different ways the AlertDialog can be used.</p>
+
+<h4>Demo</h4>
+App/Dialog/Alert Dialog
+ 
+<h4>Source files</h4>
+ * <table class="LinkTable">
+ *         <tr>
+ *             <td >src/com.example.android.apis/app/AlertDialogSamples.java</td>
+ *             <td >The Alert Dialog Samples implementation</td>
+ *         </tr>
+ *         <tr>
+ *             <td >/res/any/layout/alert_dialog.xml</td>
+ *             <td >Defines contents of the screen</td>
+ *         </tr>
+ * </table> 
+ */
+public class AlertDialogSamples extends Activity {
+    private static final int DIALOG_YES_NO_MESSAGE = 1;
+    private static final int DIALOG_YES_NO_LONG_MESSAGE = 2;
+    private static final int DIALOG_LIST = 3;
+    private static final int DIALOG_PROGRESS = 4;
+    private static final int DIALOG_SINGLE_CHOICE = 5;
+    private static final int DIALOG_MULTIPLE_CHOICE = 6;
+    private static final int DIALOG_TEXT_ENTRY = 7;
+
+    private static final int MAX_PROGRESS = 100;
+    
+    private ProgressDialog mProgressDialog;
+    private int mProgress;
+    private Handler mProgressHandler;
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+        case DIALOG_YES_NO_MESSAGE:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIcon(R.drawable.alert_dialog_icon)
+                .setTitle(R.string.alert_dialog_two_buttons_title)
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked OK so do some stuff */
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Cancel so do some stuff */
+                    }
+                })
+                .create();
+        case DIALOG_YES_NO_LONG_MESSAGE:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIcon(R.drawable.alert_dialog_icon)
+                .setTitle(R.string.alert_dialog_two_buttons_msg)
+                .setMessage(R.string.alert_dialog_two_buttons2_msg)
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+    
+                        /* User clicked OK so do some stuff */
+                    }
+                })
+                .setNeutralButton(R.string.alert_dialog_something, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Something so do some stuff */
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Cancel so do some stuff */
+                    }
+                })
+                .create();
+        case DIALOG_LIST:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setTitle(R.string.select_dialog)
+                .setItems(R.array.select_dialog_items, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+
+                        /* User clicked so do some stuff */
+                        String[] items = getResources().getStringArray(R.array.select_dialog_items);
+                        new AlertDialog.Builder(AlertDialogSamples.this)
+                                .setMessage("You selected: " + which + " , " + items[which])
+                                .show();
+                    }
+                })
+                .create();
+        case DIALOG_PROGRESS:
+            mProgressDialog = new ProgressDialog(AlertDialogSamples.this);
+            mProgressDialog.setIcon(R.drawable.alert_dialog_icon);
+            mProgressDialog.setTitle(R.string.select_dialog);
+            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+            mProgressDialog.setMax(MAX_PROGRESS);
+            mProgressDialog.setButton(getText(R.string.alert_dialog_hide), new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int whichButton) {
+
+                    /* User clicked Yes so do some stuff */
+                }
+            });
+            mProgressDialog.setButton2(getText(R.string.alert_dialog_cancel), new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int whichButton) {
+
+                    /* User clicked No so do some stuff */
+                }
+            });
+            return mProgressDialog;
+        case DIALOG_SINGLE_CHOICE:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIcon(R.drawable.alert_dialog_icon)
+                .setTitle(R.string.alert_dialog_single_choice)
+                .setSingleChoiceItems(R.array.select_dialog_items2, 0, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked on a radio button do some stuff */
+                    }
+                })
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Yes so do some stuff */
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked No so do some stuff */
+                    }
+                })
+               .create();
+        case DIALOG_MULTIPLE_CHOICE:
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIcon(R.drawable.ic_popup_reminder)
+                .setTitle(R.string.alert_dialog_multi_choice)
+                .setMultiChoiceItems(R.array.select_dialog_items3,
+                        new boolean[]{false, true, false, true, false, false, false},
+                        new DialogInterface.OnMultiChoiceClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton,
+                                    boolean isChecked) {
+
+                                /* User clicked on a check box do some stuff */
+                            }
+                        })
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked Yes so do some stuff */
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked No so do some stuff */
+                    }
+                })
+               .create();
+        case DIALOG_TEXT_ENTRY:
+            // This example shows how to add a custom layout to an AlertDialog
+            LayoutInflater factory = LayoutInflater.from(this);
+            final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
+            return new AlertDialog.Builder(AlertDialogSamples.this)
+                .setIcon(R.drawable.alert_dialog_icon)
+                .setTitle(R.string.alert_dialog_text_entry)
+                .setView(textEntryView)
+                .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+    
+                        /* User clicked OK so do some stuff */
+                    }
+                })
+                .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        /* User clicked cancel so do some stuff */
+                    }
+                })
+                .create();
+        }
+        return null;
+    }
+
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView(int)} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.alert_dialog);
+                
+        /* Display a text message with yes/no buttons and handle each message as well as the cancel action */
+        Button twoButtonsTitle = (Button) findViewById(R.id.two_buttons);
+        twoButtonsTitle.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_YES_NO_MESSAGE);
+            }
+        });
+        
+        /* Display a long text message with yes/no buttons and handle each message as well as the cancel action */
+        Button twoButtons2Title = (Button) findViewById(R.id.two_buttons2);
+        twoButtons2Title.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_YES_NO_LONG_MESSAGE);
+            }
+        });
+        
+        
+        /* Display a list of items */
+        Button selectButton = (Button) findViewById(R.id.select_button);
+        selectButton.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_LIST);
+            }
+        });
+        
+        /* Display a custom progress bar */
+        Button progressButton = (Button) findViewById(R.id.progress_button);
+        progressButton.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_PROGRESS);
+                mProgress = 0;
+                mProgressDialog.setProgress(0);
+                mProgressHandler.sendEmptyMessage(0);
+            }
+        });
+        
+        /* Display a radio button group */
+        Button radioButton = (Button) findViewById(R.id.radio_button);
+        radioButton.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_SINGLE_CHOICE);
+            }
+        });
+        
+        /* Display a list of checkboxes */
+        Button checkBox = (Button) findViewById(R.id.checkbox_button);
+        checkBox.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_MULTIPLE_CHOICE);
+            }
+        });
+        
+        /* Display a text entry dialog */
+        Button textEntry = (Button) findViewById(R.id.text_entry_button);
+        textEntry.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG_TEXT_ENTRY);
+            }
+        });
+        
+        mProgressHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                super.handleMessage(msg);
+                if (mProgress >= MAX_PROGRESS) {
+                    mProgressDialog.dismiss();
+                } else {
+                    mProgress++;
+                    mProgressDialog.incrementProgressBy(1);
+                    mProgressHandler.sendEmptyMessageDelayed(0, 100);
+                }
+            }
+        };
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
new file mode 100644
index 0000000..bb843e5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Front-end for launching {@link ContactsFilterInstrumentation} example
+ * instrumentation class.
+ */
+public class ContactsFilter extends Activity {
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.contacts_filter);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.go);
+        button.setOnClickListener(mGoListener);
+    }
+
+    private OnClickListener mGoListener = new OnClickListener() {
+        public void onClick(View v) {
+            startInstrumentation(new ComponentName(ContactsFilter.this,
+                            ContactsFilterInstrumentation.class), null, null);
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
new file mode 100644
index 0000000..04bb671
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.view.KeyEvent;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.Map;
+
+/**
+ * This is an example implementation of the {@link android.app.Instrumentation}
+ * class, allowing you to run tests against application code.  The
+ * instrumentation implementation here is loaded into the application's
+ * process, for controlling and monitoring what it does.
+ */
+public class ContactsFilterInstrumentation extends Instrumentation {
+    @Override
+    public void onCreate(Bundle arguments) {
+        super.onCreate(arguments);
+
+        // When this instrumentation is created, we simply want to start
+        // its test code off in a separate thread, which will call back
+        // to us in onStart().
+        start();
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        // First start the activity we are instrumenting -- the contacts
+        // list.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setClassName(getTargetContext(),
+                "com.android.phone.Dialer");
+        Activity activity = startActivitySync(intent);
+
+        // This is the Activity object that was started, to do with as we want.
+        Log.i("ContactsFilterInstrumentation", "Started: " + activity);
+
+        // We are going to enqueue a couple key events to simulate the user
+        // filtering the list.  This is the low-level API so we must send both
+        // down and up events.
+        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_M));
+        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_M));
+        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A));
+        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A));
+
+        // Wait for the activity to finish all of its processing.
+        waitForIdleSync();
+
+        // And we are done!
+        Log.i("ContactsFilterInstrumentation", "Done!");
+        finish(Activity.RESULT_OK, null);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsSelectInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsSelectInstrumentation.java
new file mode 100644
index 0000000..dcb8b83
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsSelectInstrumentation.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import android.view.KeyEvent;
+import android.provider.Contacts;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.Map;
+
+/**
+ * This is an example implementation of the {@link android.app.Instrumentation}
+ * class, allowing you to run tests against application code.  The
+ * instrumentation implementation here is loaded into the application's
+ * process, for controlling and monitoring what it does.
+ */
+public class ContactsSelectInstrumentation extends Instrumentation {
+    @Override
+    public void onCreate(Bundle arguments) {
+        super.onCreate(arguments);
+
+        // When this instrumentation is created, we simply want to start
+        // its test code off in a separate thread, which will call back
+        // to us in onStart().
+        start();
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        // First start the activity we are instrumenting -- the contacts
+        // list.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setClassName(getTargetContext(),
+                "com.android.phone.Dialer");
+        Activity activity = startActivitySync(intent);
+
+        // This is the Activity object that was started, to do with as we want.
+        Log.i("ContactsSelectInstrumentation", "Started: " + activity);
+
+        // Monitor for the expected start activity call.
+        ActivityMonitor am = addMonitor(IntentFilter.create(
+            Intent.ACTION_VIEW, Contacts.People.CONTENT_ITEM_TYPE), null, true);
+
+        // We are going to enqueue a couple key events to simulate the user
+        // selecting an item in the list.
+        sendKeySync(new KeyEvent(
+            KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
+        sendKeySync(new KeyEvent(
+            KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN));
+        sendKeySync(new KeyEvent(
+            KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER));
+        sendKeySync(new KeyEvent(
+            KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
+
+        // Was the expected activity started?
+        if (checkMonitorHit(am, 1)) {
+            Log.i("ContactsSelectInstrumentation", "Activity started!");
+        } else {
+            Log.i("ContactsSelectInstrumentation", "*** ACTIVITY NOT STARTED!");
+        }
+
+        // And we are done!
+        Log.i("ContactsSelectInstrumentation", "Done!");
+        finish(Activity.RESULT_OK, null);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/CustomDialogActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/CustomDialogActivity.java
new file mode 100644
index 0000000..62f0ae1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/CustomDialogActivity.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * <h3>Dialog Activity</h3>
+ * 
+ * <p>This demonstrates the how to write an activity that looks like 
+ * a pop-up dialog with a custom theme using a different text color.</p>
+ */
+public class CustomDialogActivity extends Activity {
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+        
+        // See assets/res/any/layout/dialog_activity.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.custom_dialog_activity);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/CustomTitle.java b/samples/ApiDemos/src/com/example/android/apis/app/CustomTitle.java
new file mode 100644
index 0000000..e22a5cc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/CustomTitle.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Example of how to use a custom title {@link android.view.Window#FEATURE_CUSTOM_TITLE}.
+ * <h3>CustomTitle</h3>
+
+<p>This demonstrates how a custom title can be used.</p>
+
+<h4>Demo</h4>
+App/Title/Custom Title
+ 
+<h4>Source files</h4>
+ * <table class="LinkTable">
+ *         <tr>
+ *             <td >src/com.example.android.apis/app/CustomTitle.java</td>
+ *             <td >The Custom Title implementation</td>
+ *         </tr>
+ *         <tr>
+ *             <td >/res/any/layout/custom_title.xml</td>
+ *             <td >Defines contents of the screen</td>
+ *         </tr>
+ * </table> 
+ */
+public class CustomTitle extends Activity {
+    
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView(int)} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+        setContentView(R.layout.custom_title);
+        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_1);
+        
+        final TextView leftText = (TextView) findViewById(R.id.left_text);
+        final TextView rightText = (TextView) findViewById(R.id.right_text);
+        final EditText leftTextEdit = (EditText) findViewById(R.id.left_text_edit);
+        final EditText rightTextEdit = (EditText) findViewById(R.id.right_text_edit);
+        Button leftButton = (Button) findViewById(R.id.left_text_button);
+        Button rightButton = (Button) findViewById(R.id.right_text_button);
+        
+        leftButton.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                leftText.setText(leftTextEdit.getText());
+            }
+        });
+        rightButton.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                rightText.setText(rightTextEdit.getText());
+            }
+        });
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
new file mode 100644
index 0000000..35bdf13
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.ApiDemosApplication;
+import com.example.android.apis.R;
+
+import android.app.Application;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+/**
+ * This activity is an example of a simple settings screen that has default
+ * values.
+ * <p>
+ * In order for the default values to be populated into the
+ * {@link SharedPreferences} (from the preferences XML file), the client must
+ * call
+ * {@link PreferenceManager#setDefaultValues(android.content.Context, int, boolean)}.
+ * <p>
+ * This should be called early, typically when the application is first created.
+ * This ensures any of the application's activities, services, etc. will have
+ * the default values present, even if the user has not wandered into the
+ * application's settings. For ApiDemos, this is {@link ApiDemosApplication},
+ * and you can find the call to
+ * {@link PreferenceManager#setDefaultValues(android.content.Context, int, boolean)}
+ * in its {@link ApiDemosApplication#onCreate() onCreate}.
+ */
+public class DefaultValues extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        addPreferencesFromResource(R.xml.default_values);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
new file mode 100644
index 0000000..7441b75
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DialogActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Window;
+
+import com.example.android.apis.R;
+
+/**
+ * <h3>Dialog Activity</h3>
+ * 
+ * <p>This demonstrates the how to write an activity that looks like 
+ * a pop-up dialog.</p>
+ */
+public class DialogActivity extends Activity {
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+        
+        requestWindowFeature(Window.FEATURE_LEFT_ICON);
+        
+        // See assets/res/any/layout/dialog_activity.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.dialog_activity);
+        
+        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, 
+                android.R.drawable.ic_dialog_alert);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ForwardTarget.java b/samples/ApiDemos/src/com/example/android/apis/app/ForwardTarget.java
new file mode 100644
index 0000000..ee699aa
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForwardTarget.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Example of removing yourself from the history stack after forwarding to
+ * another activity.
+ */
+public class ForwardTarget extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.forward_target);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Forwarding.java b/samples/ApiDemos/src/com/example/android/apis/app/Forwarding.java
new file mode 100644
index 0000000..ef082bf
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Forwarding.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+
+/**
+ * <p>Example of removing yourself from the history stack after forwarding to
+ * another activity. This can be useful, for example, to implement
+    a confirmation dialog before the user goes on to another activity -- once the
+    user has confirmed this operation, they should not see the dialog again if they
+go back from it.</p>
+
+<p>Note that another way to implement a confirmation dialog would be as
+an activity that returns a result to its caller.  Either approach can be
+useful depending on how it makes sense to structure the application.</p>
+
+<h4>Demo</h4>
+App/Activity/Receive Result
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/Forwarding.java</td>
+            <td class="DescrColumn">Forwards the user to another activity when its button is pressed</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">/res/any/layout/forwarding.xml</td>
+            <td class="DescrColumn">Defines contents of the Forwarding screen</td>
+        </tr>
+</table>
+ */
+public class Forwarding extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.forwarding);
+
+        // Watch for button clicks.
+        Button goButton = (Button)findViewById(R.id.go);
+        goButton.setOnClickListener(mGoListener);
+    }
+
+    private OnClickListener mGoListener = new OnClickListener()
+    {
+        public void onClick(View v)
+        {
+            // Here we start the next activity, and then call finish()
+            // so that our own will stop running and be removed from the
+            // history stack.
+            Intent intent = new Intent();
+            intent.setClass(Forwarding.this, ForwardTarget.class);
+            startActivity(intent);
+            finish();
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/HelloWorld.java b/samples/ApiDemos/src/com/example/android/apis/app/HelloWorld.java
new file mode 100644
index 0000000..1a7f698
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/HelloWorld.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Simple example of writing an application Activity.
+ * Hello World</a></h3>
+
+<p>This demonstrates the basic code needed to write a Screen activity.</p>
+
+<h4>Demo</h4>
+App/Activity/Hello World
+ 
+<h4>Source files</h4>
+ * <table class="LinkTable">
+ *         <tr>
+ *             <td >src/com.example.android.apis/app/HelloWorld.java</td>
+ *             <td >The Hello World Screen implementation</td>
+ *         </tr>
+ *         <tr>
+ *             <td >/res/any/layout/hello_world.xml</td>
+ *             <td >Defines contents of the screen</td>
+ *         </tr>
+ * </table> 
+ */
+public class HelloWorld extends Activity
+{
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/hello_world.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.hello_world);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IRemoteService.aidl b/samples/ApiDemos/src/com/example/android/apis/app/IRemoteService.aidl
new file mode 100644
index 0000000..046e3f6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IRemoteService.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.app.IRemoteServiceCallback;
+
+/**
+ * Example of defining an interface for calling on to a remote service
+ * (running in another process).
+ */
+interface IRemoteService {
+    /**
+     * Often you want to allow a service to call back to its clients.
+     * This shows how to do so, by registering a callback interface with
+     * the service.
+     */
+    void registerCallback(IRemoteServiceCallback cb);
+    
+    /**
+     * Remove a previously registered callback interface.
+     */
+    void unregisterCallback(IRemoteServiceCallback cb);
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IRemoteServiceCallback.aidl b/samples/ApiDemos/src/com/example/android/apis/app/IRemoteServiceCallback.aidl
new file mode 100644
index 0000000..4fed807
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IRemoteServiceCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+/**
+ * Example of a callback interface used by IRemoteService to send
+ * synchronous notifications back to its clients.  Note that this is a
+ * one-way interface so the server does not block waiting for the client.
+ */
+oneway interface IRemoteServiceCallback {
+    /**
+     * Called when the service has a new value for you.
+     */
+    void valueChanged(int value);
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ISecondary.aidl b/samples/ApiDemos/src/com/example/android/apis/app/ISecondary.aidl
new file mode 100644
index 0000000..98e2823
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ISecondary.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+/**
+ * Example of a secondary interface associated with a service.  (Note that
+ * the interface itself doesn't impact, it is just a matter of how you
+ * retrieve it from the service.)
+ */
+interface ISecondary {
+    /**
+     * Request the PID of this service, to do evil things with it.
+     */
+    int getPid();
+    
+    /**
+     * This demonstrates the basic types that you can use as parameters
+     * and return values in AIDL.
+     */
+    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+            double aDouble, String aString);
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
new file mode 100644
index 0000000..d44c008
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class IncomingMessage extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.incoming_message);
+
+        Button button = (Button) findViewById(R.id.notify);
+        button.setOnClickListener(new Button.OnClickListener() {
+                public void onClick(View v) {
+                    showToast();
+                    showNotification();
+                }
+            });
+    }
+
+    /**
+     * The toast pops up a quick message to the user showing what could be
+     * the text of an incoming message.  It uses a custom view to do so.
+     */
+    protected void showToast() {
+        // create the view
+        View view = inflateView(R.layout.incoming_message_panel);
+
+        // set the text in the view
+        TextView tv = (TextView)view.findViewById(R.id.message);
+        tv.setText("khtx. meet u for dinner. cul8r");
+
+        // show the toast
+        Toast toast = new Toast(this);
+        toast.setView(view);
+        toast.setDuration(Toast.LENGTH_LONG);
+        toast.show();
+    }
+
+    private View inflateView(int resource) {
+        LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        return vi.inflate(resource, null);
+    }
+
+    /**
+     * The notification is the icon and associated expanded entry in the
+     * status bar.
+     */
+    protected void showNotification() {
+        // look up the notification manager service
+        NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // The details of our fake message
+        CharSequence from = "Joe";
+        CharSequence message = "kthx. meet u for dinner. cul8r";
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, IncomingMessageView.class), 0);
+
+        // The ticker text, this uses a formatted string so our message could be localized
+        String tickerText = getString(R.string.imcoming_message_ticker_text, message);
+
+        // construct the Notification object.
+        Notification notif = new Notification(R.drawable.stat_sample, tickerText,
+                System.currentTimeMillis());
+
+        // Set the info for the views that show in the notification panel.
+        notif.setLatestEventInfo(this, from, message, contentIntent);
+
+        // after a 100ms delay, vibrate for 250ms, pause for 100 ms and
+        // then vibrate for 500ms.
+        notif.vibrate = new long[] { 100, 250, 100, 500};
+
+        // Note that we use R.layout.incoming_message_panel as the ID for
+        // the notification.  It could be any integer you want, but we use
+        // the convention of using a resource id for a string related to
+        // the notification.  It will always be a unique number within your
+        // application.
+        nm.notify(R.string.imcoming_message_ticker_text, notif);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageView.java b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageView.java
new file mode 100644
index 0000000..c3bead0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageView.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.os.Bundle;
+
+import java.util.Map;
+
+/**
+ * This activity is run as the click activity for {@link IncomingMessage}.
+ * When it comes up, it also clears the notification, because the "message"
+ * has been "read."
+ */
+public class IncomingMessageView extends Activity {
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.incoming_message_view);
+
+        // look up the notification manager service
+        NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+
+        // cancel the notification that we started in IncomingMessage
+        nm.cancel(R.string.imcoming_message_ticker_text);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Intents.java b/samples/ApiDemos/src/com/example/android/apis/app/Intents.java
new file mode 100644
index 0000000..8f02b83
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Intents.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class Intents extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.intents);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.get_music);
+        button.setOnClickListener(mGetMusicListener);
+    }
+
+    private OnClickListener mGetMusicListener = new OnClickListener() {
+        public void onClick(View v) {
+            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+            intent.setType("audio/*");
+            startActivity(Intent.createChooser(intent, "Select music"));
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LauncherShortcuts.java b/samples/ApiDemos/src/com/example/android/apis/app/LauncherShortcuts.java
new file mode 100644
index 0000000..f28deab
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LauncherShortcuts.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.widget.TextView;
+
+import com.example.android.apis.R;
+
+/**
+ * This Activity actually handles two stages of a launcher shortcut's life cycle.
+ * 
+ * 1. Your application offers to provide shortcuts to the launcher.  When
+ *    the user installs a shortcut, an activity within your application
+ *    generates the actual shortcut and returns it to the launcher, where it
+ *    is shown to the user as an icon.
+ *
+ * 2. Any time the user clicks on an installed shortcut, an intent is sent.
+ *    Typically this would then be handled as necessary by an activity within
+ *    your application.
+ *    
+ * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form
+ * of an {@link android.content.Intent} that the launcher will use to create the shortcut.
+ * 
+ * You can also implement this in an interactive way, by having your activity actually present
+ * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL,
+ * media item, or action.
+ * 
+ * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents
+ * of the incoming {@link android.content.Intent}.
+ * 
+ * In a real application, you would probably use the shortcut intent to display specific content
+ * or start a particular operation.
+ */
+public class LauncherShortcuts extends Activity {
+
+    private static final String EXTRA_KEY = "com.example.android.apis.app.LauncherShortcuts";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Resolve the intent
+
+        final Intent intent = getIntent();
+        final String action = intent.getAction();
+
+        // If the intent is a request to create a shortcut, we'll do that and exit
+
+        if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
+            setupShortcut();
+            finish();
+            return;
+        }
+
+        // If we weren't launched with a CREATE_SHORTCUT intent, simply put up an informative
+        // display.
+
+        // Inflate our UI from its XML layout description.
+
+        setContentView(R.layout.launcher_shortcuts);
+
+        // Provide a lightweight view of the Intent that launched us
+
+        TextView intentInfo = (TextView) findViewById(R.id.txt_shortcut_intent);
+        String info = intent.toString();
+        String extra = intent.getStringExtra(EXTRA_KEY);
+        if (extra != null) {
+            info = info + " " + extra;
+        }
+        intentInfo.setText(info);
+    }
+
+    /**
+     * This function creates a shortcut and returns it to the caller.  There are actually two 
+     * intents that you will send back.
+     * 
+     * The first intent serves as a container for the shortcut and is returned to the launcher by 
+     * setResult().  This intent must contain three fields:
+     * 
+     * <ul>
+     * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li>
+     * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with
+     * the shortcut.</li>
+     * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a
+     * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as
+     * a drawable resource.</li>
+     * </ul>
+     * 
+     * If you use a simple drawable resource, note that you must wrapper it using
+     * {@link android.content.Intent.ShortcutIconResource}, as shown below.  This is required so
+     * that the launcher can access resources that are stored in your application's .apk file.  If 
+     * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras 
+     * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}.
+     * 
+     * The shortcut intent can be any intent that you wish the launcher to send, when the user 
+     * clicks on the shortcut.  Typically this will be {@link android.content.Intent#ACTION_VIEW} 
+     * with an appropriate Uri for your content, but any Intent will work here as long as it 
+     * triggers the desired action within your Activity.
+     */
+    private void setupShortcut() {
+        // First, set up the shortcut intent.  For this example, we simply create an intent that
+        // will bring us directly back to this activity.  A more typical implementation would use a 
+        // data Uri in order to display a more specific result, or a custom action in order to 
+        // launch a specific operation.
+
+        Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);
+        shortcutIntent.setClassName(this, this.getClass().getName());
+        shortcutIntent.putExtra(EXTRA_KEY, "ApiDemos Provided This Shortcut");
+
+        // Then, set up the container intent (the response to the caller)
+
+        Intent intent = new Intent();
+        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
+        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.shortcut_name));
+        Parcelable iconResource = Intent.ShortcutIconResource.fromContext(
+                this,  R.drawable.app_sample_code);
+        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
+
+        // Now, return the result to the launcher
+
+        setResult(RESULT_OK, intent);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java b/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java
new file mode 100644
index 0000000..aa151fe
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LaunchingPreferences.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.LinearLayout.LayoutParams;
+
+/**
+ * Demonstrates launching a PreferenceActivity and grabbing a value it saved.
+ */
+public class LaunchingPreferences extends Activity implements OnClickListener {
+
+    private static final int REQUEST_CODE_PREFERENCES = 1;
+    
+    private TextView mCounterText;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        /*
+         * If this were my app's main activity, I would load the default values
+         * so they're set even if the user does not go into the preferences
+         * screen. Another good place to call this method would be from a
+         * subclass of Application, so your default values would be loaded
+         * regardless of entry into your application (for example, a service or
+         * activity).
+         */  
+        PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
+        
+        // Simple layout
+        LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.VERTICAL);
+        setContentView(layout);
+        
+        // Create a simple button that will launch the preferences
+        Button launchPreferences = new Button(this);
+        launchPreferences.setText(getString(R.string.launch_preference_activity));
+        launchPreferences.setOnClickListener(this);
+        layout.addView(launchPreferences, new LayoutParams(LayoutParams.FILL_PARENT,
+                LayoutParams.WRAP_CONTENT));
+        
+        mCounterText = new TextView(this);
+        layout.addView(mCounterText, new LayoutParams(LayoutParams.FILL_PARENT,
+                LayoutParams.WRAP_CONTENT));
+        
+        updateCounterText();
+    }
+
+    public void onClick(View v) {
+        
+        // When the button is clicked, launch an activity through this intent
+        Intent launchPreferencesIntent = new Intent().setClass(this, AdvancedPreferences.class);
+        
+        // Make it a subactivity so we know when it returns
+        startActivityForResult(launchPreferencesIntent, REQUEST_CODE_PREFERENCES);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        
+        // The preferences returned if the request code is what we had given
+        // earlier in startSubActivity
+        if (requestCode == REQUEST_CODE_PREFERENCES) {
+            // Read a sample value they have set
+            updateCounterText();
+        }
+    }
+
+    private void updateCounterText() {
+        // Since we're in the same package, we can use this context to get
+        // the default shared preferences
+        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+        final int counter = sharedPref.getInt(AdvancedPreferences.KEY_MY_PREFERENCE, 0);
+        mCounterText.setText(getString(R.string.counter_value_is) + " " + counter);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
new file mode 100644
index 0000000..1bb26e9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Front-end for launching {@link LocalSampleInstrumentation} example
+ * instrumentation class.
+ */
+public class LocalSample extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.local_sample);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.go);
+        button.setOnClickListener(mGoListener);
+    }
+
+    private OnClickListener mGoListener = new OnClickListener() {
+        public void onClick(View v) {
+            startInstrumentation(new ComponentName(LocalSample.this,
+                    LocalSampleInstrumentation.class), null, null);
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
new file mode 100644
index 0000000..e0f6163
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.view.KeyEvent;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.Map;
+
+/**
+ * This is an example implementation of the {@link android.app.Instrumentation}
+ * class demonstrating instrumentation against one of this application's sample
+ * activities.
+ */
+public class LocalSampleInstrumentation extends Instrumentation {
+    public abstract static class ActivityRunnable implements Runnable {
+        public final Activity activity;
+        public ActivityRunnable(Activity _activity) {
+            activity = _activity;
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        super.onCreate(arguments);
+
+        // When this instrumentation is created, we simply want to start
+        // its test code off in a separate thread, which will call back
+        // to us in onStart().
+        start();
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        // First start the activity we are instrumenting -- the save/restore
+        // state sample, which has a nice edit text into which we can write
+        // text.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setClass(getTargetContext(), SaveRestoreState.class);
+        SaveRestoreState activity = (SaveRestoreState)startActivitySync(intent);
+
+        // This is the Activity object that was started, to do with as we want.
+        Log.i("LocalSampleInstrumentation",
+              "Initial text: " + activity.getSavedText());
+
+        // Clear the text so we start fresh.
+        runOnMainSync(new ActivityRunnable(activity) {
+            public void run() {
+                ((SaveRestoreState)activity).setSavedText("");
+            }
+        });
+
+        // Act like the user is typing some text.
+        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT));
+        sendCharacterSync(KeyEvent.KEYCODE_H);
+        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT));
+        sendCharacterSync(KeyEvent.KEYCODE_E);
+        sendCharacterSync(KeyEvent.KEYCODE_L);
+        sendCharacterSync(KeyEvent.KEYCODE_L);
+        sendCharacterSync(KeyEvent.KEYCODE_O);
+
+        // Wait for the activity to finish all of its processing.
+        waitForIdleSync();
+
+        // Retrieve the text we should have written...
+        Log.i("LocalSampleInstrumentation",
+              "Final text: " + activity.getSavedText());
+
+        // And we are done!
+        Log.i("ContactsFilterInstrumentation", "Done!");
+        finish(Activity.RESULT_OK, null);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
new file mode 100644
index 0000000..8791578
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.widget.Toast;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * This is an example of implementing an application service that runs locally
+ * in the same process as the application.  The {@link LocalServiceController}
+ * and {@link LocalServiceBinding} classes show how to interact with the
+ * service.
+ *
+ * <p>Notice the use of the {@link NotificationManager} when interesting things
+ * happen in the service.  This is generally how background services should
+ * interact with the user, rather than doing something more disruptive such as
+ * calling startActivity().
+ */
+public class LocalService extends Service {
+    private NotificationManager mNM;
+
+    /**
+     * Class for clients to access.  Because we know this service always
+     * runs in the same process as its clients, we don't need to deal with
+     * IPC.
+     */
+    public class LocalBinder extends Binder {
+        LocalService getService() {
+            return LocalService.this;
+        }
+    }
+    
+    @Override
+    public void onCreate() {
+        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // Display a notification about us starting.  We put an icon in the status bar.
+        showNotification();
+    }
+
+    @Override
+    public void onDestroy() {
+        // Cancel the persistent notification.
+        mNM.cancel(R.string.local_service_started);
+
+        // Tell the user we stopped.
+        Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    // This is the object that receives interactions from clients.  See
+    // RemoteService for a more complete example.
+    private final IBinder mBinder = new LocalBinder();
+
+    /**
+     * Show a notification while this service is running.
+     */
+    private void showNotification() {
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(R.string.local_service_started);
+
+        // Set the icon, scrolling text and timestamp
+        Notification notification = new Notification(R.drawable.stat_sample, text,
+                System.currentTimeMillis());
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, LocalServiceController.class), 0);
+
+        // Set the info for the views that show in the notification panel.
+        notification.setLatestEventInfo(this, getText(R.string.local_service_label),
+                       text, contentIntent);
+
+        // Send the notification.
+        // We use a layout id because it is a unique number.  We use it later to cancel.
+        mNM.notify(R.string.local_service_started, notification);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceBinding.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceBinding.java
new file mode 100644
index 0000000..ddcfad5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceBinding.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+
+/**
+ * <p>Example of binding and unbinding to the {@link LocalService}.
+ * This demonstrates the implementation of a service which the client will
+ * bind to, receiving an object through which it can communicate with the service.</p>
+ */
+public class LocalServiceBinding extends Activity {
+    private boolean mIsBound;
+    private LocalService mBoundService;
+
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.local_service_binding);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.bind);
+        button.setOnClickListener(mBindListener);
+        button = (Button)findViewById(R.id.unbind);
+        button.setOnClickListener(mUnbindListener);
+    }
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            // This is called when the connection with the service has been
+            // established, giving us the service object we can use to
+            // interact with the service.  Because we have bound to a explicit
+            // service that we know is running in our own process, we can
+            // cast its IBinder to a concrete class and directly access it.
+            mBoundService = ((LocalService.LocalBinder)service).getService();
+            
+            // Tell the user about this for our demo.
+            Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected,
+                    Toast.LENGTH_SHORT).show();
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            // This is called when the connection with the service has been
+            // unexpectedly disconnected -- that is, its process crashed.
+            // Because it is running in our same process, we should never
+            // see this happen.
+            mBoundService = null;
+            Toast.makeText(LocalServiceBinding.this, R.string.local_service_disconnected,
+                    Toast.LENGTH_SHORT).show();
+        }
+    };
+
+    private OnClickListener mBindListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Establish a connection with the service.  We use an explicit
+            // class name because we want a specific service implementation that
+            // we know will be running in our own process (and thus won't be
+            // supporting component replacement by other applications).
+            bindService(new Intent(LocalServiceBinding.this, 
+                    LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
+            mIsBound = true;
+        }
+    };
+
+    private OnClickListener mUnbindListener = new OnClickListener() {
+        public void onClick(View v) {
+            if (mIsBound) {
+                // Detach our existing connection.
+                unbindService(mConnection);
+                mIsBound = false;
+            }
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceController.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceController.java
new file mode 100644
index 0000000..6041249
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceController.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+
+/**
+ * <p>Example of explicitly starting and stopping the {@link LocalService}.
+ * This demonstrates the implementation of a service that runs in the same
+ * process as the rest of the application, which is explicitly started and stopped
+ * as desired.</p>
+ */
+public class LocalServiceController extends Activity {
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.local_service_controller);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.start);
+        button.setOnClickListener(mStartListener);
+        button = (Button)findViewById(R.id.stop);
+        button.setOnClickListener(mStopListener);
+    }
+
+    private OnClickListener mStartListener = new OnClickListener() {
+        public void onClick(View v)
+        {
+            // Make sure the service is started.  It will continue running
+            // until someone calls stopService().  The Intent we use to find
+            // the service explicitly specifies our service component, because
+            // we want it running in our own process and don't want other
+            // applications to replace it.
+            startService(new Intent(LocalServiceController.this,
+                    LocalService.class));
+        }
+    };
+
+    private OnClickListener mStopListener = new OnClickListener() {
+        public void onClick(View v)
+        {
+            // Cancel a previous call to startService().  Note that the
+            // service will not actually stop at this point if there are
+            // still bound clients.
+            stopService(new Intent(LocalServiceController.this,
+                    LocalService.class));
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/MenuInflateFromXml.java b/samples/ApiDemos/src/com/example/android/apis/app/MenuInflateFromXml.java
new file mode 100644
index 0000000..f51b3b8
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/MenuInflateFromXml.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.ArrayAdapter;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Demonstrates inflating menus from XML. There are different menu XML resources
+ * that the user can choose to inflate. First, select an example resource from
+ * the spinner, and then hit the menu button. To choose another, back out of the
+ * activity and start over.
+ */
+public class MenuInflateFromXml extends Activity {
+    /**
+     * Different example menu resources.
+     */
+    private static final int sMenuExampleResources[] = {
+        R.menu.title_only, R.menu.title_icon, R.menu.submenu, R.menu.groups,
+        R.menu.checkable, R.menu.shortcuts, R.menu.order, R.menu.category_order,
+        R.menu.visible, R.menu.disabled
+    };
+    
+    /**
+     * Names corresponding to the different example menu resources.
+     */
+    private static final String sMenuExampleNames[] = {
+        "Title only", "Title and Icon", "Submenu", "Groups",
+        "Checkable", "Shortcuts", "Order", "Category and Order",
+        "Visible", "Disabled"
+    };
+   
+    /**
+     * Lets the user choose a menu resource.
+     */
+    private Spinner mSpinner;
+
+    /**
+     * Shown as instructions.
+     */
+    private TextView mInstructionsText;
+    
+    /**
+     * Safe to hold on to this.
+     */
+    private Menu mMenu;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Create a simple layout
+        LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.VERTICAL);
+        
+        // Create the spinner to allow the user to choose a menu XML
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, sMenuExampleNames); 
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mSpinner = new Spinner(this);
+        // When programmatically creating views, make sure to set an ID
+        // so it will automatically save its instance state
+        mSpinner.setId(R.id.spinner);
+        mSpinner.setAdapter(adapter);
+        
+        // Add the spinner
+        layout.addView(mSpinner,
+                new LinearLayout.LayoutParams(
+                        LinearLayout.LayoutParams.FILL_PARENT,
+                        LinearLayout.LayoutParams.WRAP_CONTENT));
+
+        // Create help text
+        mInstructionsText = new TextView(this);
+        mInstructionsText.setText(getResources().getString(
+                R.string.menu_from_xml_instructions_press_menu));
+        
+        // Add the help, make it look decent
+        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.FILL_PARENT,
+                LinearLayout.LayoutParams.WRAP_CONTENT);
+        lp.setMargins(10, 10, 10, 10);
+        layout.addView(mInstructionsText, lp);
+        
+        // Set the layout as our content view
+        setContentView(layout);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Hold on to this
+        mMenu = menu;
+        
+        // Inflate the currently selected menu XML resource.
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(sMenuExampleResources[mSpinner.getSelectedItemPosition()], menu);
+        
+        // Disable the spinner since we've already created the menu and the user
+        // can no longer pick a different menu XML.
+        mSpinner.setEnabled(false);
+        
+        // Change instructions
+        mInstructionsText.setText(getResources().getString(
+                R.string.menu_from_xml_instructions_go_back));
+        
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            // For "Title only": Examples of matching an ID with one assigned in
+            //                   the XML
+            case R.id.jump:
+                Toast.makeText(this, "Jump up in the air!", Toast.LENGTH_SHORT).show();
+                return true;
+
+            case R.id.dive:
+                Toast.makeText(this, "Dive into the water!", Toast.LENGTH_SHORT).show();
+                return true;
+
+            // For "Groups": Toggle visibility of grouped menu items with
+            //               nongrouped menu items
+            case R.id.browser_visibility:
+                // The refresh item is part of the browser group
+                final boolean shouldShowBrowser = !mMenu.findItem(R.id.refresh).isVisible();
+                mMenu.setGroupVisible(R.id.browser, shouldShowBrowser);
+                break;
+                
+            case R.id.email_visibility:
+                // The reply item is part of the email group
+                final boolean shouldShowEmail = !mMenu.findItem(R.id.reply).isVisible();
+                mMenu.setGroupVisible(R.id.email, shouldShowEmail);
+                break;
+                
+            // Generic catch all for all the other menu resources
+            default:
+                // Don't toast text when a submenu is clicked
+                if (!item.hasSubMenu()) {
+                    Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show();
+                    return true;
+                }
+                break;
+        }
+        
+        return false;
+    }
+    
+    
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java b/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java
new file mode 100644
index 0000000..967c181
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/MyPreference.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * This is an example of a custom preference type. The preference counts the
+ * number of clicks it has received and stores/retrieves it from the storage.
+ */
+public class MyPreference extends Preference {
+    private int mClickCounter;
+    
+    // This is the constructor called by the inflater
+    public MyPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        
+        setWidgetLayoutResource(R.layout.preference_widget_mypreference);        
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        
+        // Set our custom views inside the layout
+        final TextView myTextView = (TextView) view.findViewById(R.id.mypreference_widget);
+        if (myTextView != null) {
+            myTextView.setText(String.valueOf(mClickCounter));
+        }
+    }
+
+    @Override
+    protected void onClick() {
+        int newValue = mClickCounter + 1;
+        // Give the client a chance to ignore this change if they deem it
+        // invalid
+        if (!callChangeListener(newValue)) {
+            // They don't want the value to be set
+            return;
+        }
+        
+        // Increment counter
+        mClickCounter = newValue;
+        
+        // Save to persistent storage (this method will make sure this
+        // preference should be persistent, along with other useful checks)
+        persistInt(mClickCounter);
+        
+        // Data has changed, notify so UI can be refreshed!
+        notifyChanged();
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray a, int index) {
+        // This preference type's value type is Integer, so we read the default
+        // value from the attributes as an Integer.
+        return a.getInteger(index, 0);
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        if (restoreValue) {
+            // Restore state
+            mClickCounter = getPersistedInt(mClickCounter);
+        } else {
+            // Set state
+            int value = (Integer) defaultValue;
+            mClickCounter = value;
+            persistInt(value);
+        }
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        /*
+         * Suppose a client uses this preference type without persisting. We
+         * must save the instance state so it is able to, for example, survive
+         * orientation changes.
+         */
+        
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+
+        // Save the instance state
+        final SavedState myState = new SavedState(superState);
+        myState.clickCounter = mClickCounter;
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (!state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+     
+        // Restore the instance state
+        SavedState myState = (SavedState) state;
+        super.onRestoreInstanceState(myState.getSuperState());
+        mClickCounter = myState.clickCounter;
+        notifyChanged();
+    }
+    
+    /**
+     * SavedState, a subclass of {@link BaseSavedState}, will store the state
+     * of MyPreference, a subclass of Preference.
+     * <p>
+     * It is important to always call through to super methods.
+     */
+    private static class SavedState extends BaseSavedState {
+        int clickCounter;
+        
+        public SavedState(Parcel source) {
+            super(source);
+            
+            // Restore the click counter
+            clickCounter = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            
+            // Save the click counter
+            dest.writeInt(clickCounter);
+        }
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+    
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java b/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
new file mode 100644
index 0000000..a6c20ea
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+
+
+/**
+ * Activity used by StatusBarNotification to show the notification to the user.
+ */
+public class NotificationDisplay extends Activity implements View.OnClickListener {
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+    protected void onCreate(Bundle icicle) {
+        // Be sure to call the super class.
+        super.onCreate(icicle);
+
+        // Have the system blur any windows behind this one.
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
+                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+        
+        RelativeLayout container = new RelativeLayout(this);
+        
+        ImageButton button = new ImageButton(this);
+        button.setImageResource(getIntent().getIntExtra("moodimg", 0));
+        button.setOnClickListener(this);
+        
+        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
+                RelativeLayout.LayoutParams.WRAP_CONTENT,
+                RelativeLayout.LayoutParams.WRAP_CONTENT);
+        lp.addRule(RelativeLayout.CENTER_IN_PARENT);
+        
+        container.addView(button, lp);
+        
+        setContentView(container);
+    }
+
+    public void onClick(View v) {
+        // The user has confirmed this notification, so remove it.
+        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
+                .cancel(R.layout.status_bar_notifications);
+        
+        // Pressing on the button brings the user back to our mood ring,
+        // as part of the api demos app.  Note the use of NEW_TASK here,
+        // since the notification display activity is run as a separate task.
+        Intent intent = new Intent(this, StatusBarNotifications.class);
+        intent.setAction(Intent.ACTION_MAIN);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        startActivity(intent);
+        
+        // We're done.
+        finish();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyWithText.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyWithText.java
new file mode 100644
index 0000000..950ded9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyWithText.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.Button;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Toast;
+
+/**
+ * When you push the button on this Activity, it creates a {@link Toast} object and
+ * using the Toast method.
+ * @see Toast
+ * @see Toast#makeText(android.content.Context,int,int)
+ * @see Toast#makeText(android.content.Context,java.lang.CharSequence,int)
+ * @see Toast#LENGTH_SHORT
+ * @see Toast#LENGTH_LONG
+ */
+public class NotifyWithText extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.notify_with_text);
+
+        Button button;
+
+        // short notification
+        button = (Button) findViewById(R.id.short_notify);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                // Note that we create the Toast object and call the show() method
+                // on it all on one line.  Most uses look like this, but there
+                // are other methods on Toast that you can call to configure how
+                // it appears.
+                //
+                // Note also that we use the version of makeText that takes a
+                // resource id (R.string.short_notification_text).  There is also
+                // a version that takes a CharSequence if you must construct
+                // the text yourself.
+                Toast.makeText(NotifyWithText.this, R.string.short_notification_text,
+                    Toast.LENGTH_SHORT).show();
+            }
+        });
+
+        // long notification
+        // The only difference here is that the notification stays up longer.
+        // You might want to use this if there is more text that they're going
+        // to read.
+        button = (Button) findViewById(R.id.long_notify);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                Toast.makeText(NotifyWithText.this, R.string.long_notification_text,
+                    Toast.LENGTH_LONG).show();
+            }
+        });
+
+
+
+
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
new file mode 100644
index 0000000..a0de699
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+
+/**
+ * Controller to start and stop a service. The serivce will update a status bar
+ * notification every 5 seconds for a minute.
+ */
+public class NotifyingController extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.notifying_controller);
+
+        Button button = (Button) findViewById(R.id.notifyStart);
+        button.setOnClickListener(mStartListener);
+        button = (Button) findViewById(R.id.notifyStop);
+        button.setOnClickListener(mStopListener);
+    }
+
+    private OnClickListener mStartListener = new OnClickListener() {
+        public void onClick(View v) {
+            startService(new Intent(NotifyingController.this, 
+                    NotifyingService.class));
+        }
+    };
+
+    private OnClickListener mStopListener = new OnClickListener() {
+        public void onClick(View v) {
+            stopService(new Intent(NotifyingController.this, 
+                    NotifyingService.class));
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
new file mode 100644
index 0000000..e580978
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.ConditionVariable;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.widget.RemoteViews;
+
+/**
+ * This is an example of service that will update its status bar balloon 
+ * every 5 seconds for a minute.
+ * 
+ */
+public class NotifyingService extends Service {
+    
+    // Use a layout id for a unique identifier
+    private static int MOOD_NOTIFICATIONS = R.layout.status_bar_notifications;
+
+    // variable which controls the notification thread 
+    private ConditionVariable mCondition;
+ 
+    @Override
+    public void onCreate() {
+        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+
+        // Start up the thread running the service.  Note that we create a
+        // separate thread because the service normally runs in the process's
+        // main thread, which we don't want to block.
+        Thread notifyingThread = new Thread(null, mTask, "NotifyingService");
+        mCondition = new ConditionVariable(false);
+        notifyingThread.start();
+    }
+
+    @Override
+    public void onDestroy() {
+        // Cancel the persistent notification.
+        mNM.cancel(MOOD_NOTIFICATIONS);
+        // Stop the thread from generating further notifications
+        mCondition.open();
+    }
+
+    private Runnable mTask = new Runnable() {
+        public void run() {
+            for (int i = 0; i < 4; ++i) {
+                showNotification(R.drawable.stat_happy,
+                        R.string.status_bar_notifications_happy_message);
+                if (mCondition.block(5 * 1000)) 
+                    break;
+                showNotification(R.drawable.stat_neutral,
+                        R.string.status_bar_notifications_ok_message);
+                if (mCondition.block(5 * 1000)) 
+                    break;
+                showNotification(R.drawable.stat_sad,
+                        R.string.status_bar_notifications_sad_message);
+                if (mCondition.block(5 * 1000)) 
+                    break;
+            }
+            // Done with our work...  stop the service!
+            NotifyingService.this.stopSelf();
+        }
+    };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+    
+    private void showNotification(int moodId, int textId) {
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(textId);
+
+        // Set the icon, scrolling text and timestamp.
+        // Note that in this example, we pass null for tickerText.  We update the icon enough that
+        // it is distracting to show the ticker text every time it changes.  We strongly suggest
+        // that you do this as well.  (Think of of the "New hardware found" or "Network connection
+        // changed" messages that always pop up)
+        Notification notification = new Notification(moodId, null, System.currentTimeMillis());
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, NotifyingController.class), 0);
+
+        // Set the info for the views that show in the notification panel.
+        notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title),
+                       text, contentIntent);
+
+        // Send the notification.
+        // We use a layout id because it is a unique number.  We use it later to cancel.
+        mNM.notify(MOOD_NOTIFICATIONS, notification);
+    }
+
+    // This is the object that receives interactions from clients.  See
+    // RemoteService for a more complete example.
+    private final IBinder mBinder = new Binder() {
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply,
+                int flags) throws RemoteException {
+            return super.onTransact(code, data, reply, flags);
+        }
+    };
+
+    private NotificationManager mNM;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/OneShotAlarm.java b/samples/ApiDemos/src/com/example/android/apis/app/OneShotAlarm.java
new file mode 100644
index 0000000..ec7e074
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/OneShotAlarm.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.widget.Toast;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * This is an example of implement an {@link BroadcastReceiver} for an alarm that
+ * should occur once.
+ * <p>
+ * When the alarm goes off, we show a <i>Toast</i>, a quick message.
+ */
+public class OneShotAlarm extends BroadcastReceiver
+{
+    @Override
+    public void onReceive(Context context, Intent intent)
+    {
+        Toast.makeText(context, R.string.one_shot_received, Toast.LENGTH_SHORT).show();
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PersistentState.java b/samples/ApiDemos/src/com/example/android/apis/app/PersistentState.java
new file mode 100644
index 0000000..618a692
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PersistentState.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * Simple example of using persistent preferences to retain a screen's state.
+ * <p>This can be used as an alternative to the normal
+ * <code>onSaveInstanceState()</code> mechanism, if you
+ * wish the state to persist even after an activity is finished.</p>
+ *
+ * <p>Note that using this approach requires more care, since you are sharing
+ * the persistent state potentially across multiple instances of the activity.
+ * In particular, if you allow a new instance of the activity to be launched
+ * directly on top of the existing instance, the state can get out of sync
+ * because the new instance is resumed before the old one is paused.</p>
+ *
+ * <p>For any persistent state that is not simplistic, a content
+ * provider is often a better choice.</p>
+ *
+ * <p>In this example we are currently saving and restoring the state of the
+ * top text editor, but not of the bottom text editor.  You can see the difference
+ * by editing the two text fields, then going back from the activity and
+ * starting it again.</p>
+ *
+ * <h4>Demo</h4>
+ * App/Activity/Save &amp; Restore State
+ *
+ * <h4>Source files</h4>
+ * <table class="LinkTable">
+ *         <tr>
+ *             <td class="LinkColumn">src/com.example.android.apis/app/PersistentState.java</td>
+ *             <td class="DescrColumn">The Save/Restore Screen implementation</td>
+ *         </tr>
+ *         <tr>
+ *             <td class="LinkColumn">/res/any/layout/save_restore_state.xml</td>
+ *             <td class="DescrColumn">Defines contents of the screen</td>
+ *         </tr>
+ * </table>
+ *
+ */
+public class PersistentState extends Activity
+{
+    /**
+     * Initialization of the Activity after it is first created.  Here we use
+     * {@link android.app.Activity#setContentView setContentView()} to set up
+     * the Activity's content, and retrieve the EditText widget whose state we
+     * will persistent.
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/save_restore_state.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.save_restore_state);
+
+        // Set message to be appropriate for this screen.
+        ((TextView)findViewById(R.id.msg)).setText(R.string.persistent_msg);
+
+        // Retrieve the EditText widget whose state we will save.
+        mSaved = (EditText)findViewById(R.id.saved);
+    }
+
+    /**
+     * Upon being resumed we can retrieve the current state.  This allows us
+     * to update the state if it was changed at any time while paused.
+     */
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        SharedPreferences prefs = getPreferences(0); 
+        String restoredText = prefs.getString("text", null);
+        if (restoredText != null) {
+            mSaved.setText(restoredText, TextView.BufferType.EDITABLE);
+
+            int selectionStart = prefs.getInt("selection-start", -1);
+            int selectionEnd = prefs.getInt("selection-end", -1);
+            if (selectionStart != -1 && selectionEnd != -1) {
+                mSaved.setSelection(selectionStart, selectionEnd);
+            }
+        }
+    }
+
+    /**
+     * Any time we are paused we need to save away the current state, so it
+     * will be restored correctly when we are resumed.
+     */
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        SharedPreferences.Editor editor = getPreferences(0).edit();
+        editor.putString("text", mSaved.getText().toString());
+        editor.putInt("selection-start", mSaved.getSelectionStart());
+        editor.putInt("selection-end", mSaved.getSelectionEnd());
+        editor.commit();
+    }
+
+    private EditText mSaved;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
new file mode 100644
index 0000000..27c22de
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PreferenceDependencies.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class PreferenceDependencies extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        addPreferencesFromResource(R.xml.preference_dependencies);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java
new file mode 100644
index 0000000..be22b49
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromCode.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+
+import com.example.android.apis.R;
+
+public class PreferencesFromCode extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setPreferenceScreen(createPreferenceHierarchy());
+    }
+
+    private PreferenceScreen createPreferenceHierarchy() {
+        // Root
+        PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
+        
+        // Inline preferences 
+        PreferenceCategory inlinePrefCat = new PreferenceCategory(this);
+        inlinePrefCat.setTitle(R.string.inline_preferences);
+        root.addPreference(inlinePrefCat);
+        
+        // Toggle preference
+        CheckBoxPreference togglePref = new CheckBoxPreference(this);
+        togglePref.setKey("toggle_preference");
+        togglePref.setTitle(R.string.title_toggle_preference);
+        togglePref.setSummary(R.string.summary_toggle_preference);
+        inlinePrefCat.addPreference(togglePref);
+                
+        // Dialog based preferences
+        PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this);
+        dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences);
+        root.addPreference(dialogBasedPrefCat);
+
+        // Edit text preference
+        EditTextPreference editTextPref = new EditTextPreference(this);
+        editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference);
+        editTextPref.setKey("edittext_preference");
+        editTextPref.setTitle(R.string.title_edittext_preference);
+        editTextPref.setSummary(R.string.summary_edittext_preference);
+        dialogBasedPrefCat.addPreference(editTextPref);
+        
+        // List preference
+        ListPreference listPref = new ListPreference(this);
+        listPref.setEntries(R.array.entries_list_preference);
+        listPref.setEntryValues(R.array.entryvalues_list_preference);
+        listPref.setDialogTitle(R.string.dialog_title_list_preference);
+        listPref.setKey("list_preference");
+        listPref.setTitle(R.string.title_list_preference);
+        listPref.setSummary(R.string.summary_list_preference);
+        dialogBasedPrefCat.addPreference(listPref);
+        
+        // Launch preferences
+        PreferenceCategory launchPrefCat = new PreferenceCategory(this);
+        launchPrefCat.setTitle(R.string.launch_preferences);
+        root.addPreference(launchPrefCat);
+
+        /*
+         * The Preferences screenPref serves as a screen break (similar to page
+         * break in word processing). Like for other preference types, we assign
+         * a key here so that it is able to save and restore its instance state.
+         */
+        // Screen preference
+        PreferenceScreen screenPref = getPreferenceManager().createPreferenceScreen(this);
+        screenPref.setKey("screen_preference");
+        screenPref.setTitle(R.string.title_screen_preference);
+        screenPref.setSummary(R.string.summary_screen_preference);
+        launchPrefCat.addPreference(screenPref);
+        
+        /*
+         * You can add more preferences to screenPref that will be shown on the
+         * next screen.
+         */
+        
+        // Example of next screen toggle preference
+        CheckBoxPreference nextScreenCheckBoxPref = new CheckBoxPreference(this);
+        nextScreenCheckBoxPref.setKey("next_screen_toggle_preference");
+        nextScreenCheckBoxPref.setTitle(R.string.title_next_screen_toggle_preference);
+        nextScreenCheckBoxPref.setSummary(R.string.summary_next_screen_toggle_preference);
+        screenPref.addPreference(nextScreenCheckBoxPref);
+        
+        // Intent preference
+        PreferenceScreen intentPref = getPreferenceManager().createPreferenceScreen(this);
+        intentPref.setIntent(new Intent().setAction(Intent.ACTION_VIEW)
+                .setData(Uri.parse("http://www.android.com")));
+        intentPref.setTitle(R.string.title_intent_preference);
+        intentPref.setSummary(R.string.summary_intent_preference);
+        launchPrefCat.addPreference(intentPref);
+        
+        // Preference attributes
+        PreferenceCategory prefAttrsCat = new PreferenceCategory(this);
+        prefAttrsCat.setTitle(R.string.preference_attributes);
+        root.addPreference(prefAttrsCat);
+        
+        // Visual parent toggle preference
+        CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this);
+        parentCheckBoxPref.setTitle(R.string.title_parent_preference);
+        parentCheckBoxPref.setSummary(R.string.summary_parent_preference);
+        prefAttrsCat.addPreference(parentCheckBoxPref);
+        
+        // Visual child toggle preference
+        // See res/values/attrs.xml for the <declare-styleable> that defines
+        // TogglePrefAttrs.
+        TypedArray a = obtainStyledAttributes(R.styleable.TogglePrefAttrs);
+        CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this);
+        childCheckBoxPref.setTitle(R.string.title_child_preference);
+        childCheckBoxPref.setSummary(R.string.summary_child_preference);
+        childCheckBoxPref.setLayoutResource(
+                a.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild,
+                        0));
+        prefAttrsCat.addPreference(childCheckBoxPref);
+        a.recycle();
+        
+        return root;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
new file mode 100644
index 0000000..23461c6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+
+public class PreferencesFromXml extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Load the preferences from an XML resource
+        addPreferencesFromResource(R.xml.preferences);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java b/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
new file mode 100644
index 0000000..4e248b9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import java.util.Map;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.text.Editable;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.util.Map;
+
+/**
+ * Shows how an activity can send data to its launching activity when done.y.
+ * <p>This can be used, for example, to implement a dialog alowing the user to
+pick an e-mail address or image -- the picking activity sends the selected
+data back to the originating activity when done.</p>
+
+<p>The example here is composed of two activities: ReceiveResult launches
+the picking activity and receives its results; SendResult allows the user
+to pick something and sends the selection back to its caller.  Implementing
+this functionality involves the
+{@link android.app.Activity#setResult setResult()} method for sending a
+result and
+{@link android.app.Activity#onActivityResult onActivityResult()} to
+receive it.</p>
+
+<h4>Demo</h4>
+App/Activity/Receive Result
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/ReceiveResult.java</td>
+            <td class="DescrColumn">Launches pick activity and receives its result</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/SendResult.java</td>
+            <td class="DescrColumn">Allows user to pick an option and sends it back to its caller</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">/res/any/layout/receive_result.xml</td>
+            <td class="DescrColumn">Defines contents of the ReceiveResult screen</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">/res/any/layout/send_result.xml</td>
+            <td class="DescrColumn">Defines contents of the SendResult screen</td>
+        </tr>
+</table>
+
+ */
+public class ReceiveResult extends Activity {
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/hello_world.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.receive_result);
+
+        // Retrieve the TextView widget that will display results.
+        mResults = (TextView)findViewById(R.id.results);
+
+        // This allows us to later extend the text buffer.
+        mResults.setText(mResults.getText(), TextView.BufferType.EDITABLE);
+
+        // Watch for button clicks.
+        Button getButton = (Button)findViewById(R.id.get);
+        getButton.setOnClickListener(mGetListener);
+    }
+
+    /**
+     * This method is called when the sending activity has finished, with the
+     * result it supplied.
+     * 
+     * @param requestCode The original request code as given to
+     *                    startActivity().
+     * @param resultCode From sending activity as per setResult().
+     * @param data From sending activity as per setResult().
+     */
+    @Override
+	protected void onActivityResult(int requestCode, int resultCode,
+		Intent data) {
+        // You can use the requestCode to select between multiple child
+        // activities you may have started.  Here there is only one thing
+        // we launch.
+        if (requestCode == GET_CODE) {
+
+            // We will be adding to our text.
+            Editable text = (Editable)mResults.getText();
+
+            // This is a standard resultCode that is sent back if the
+            // activity doesn't supply an explicit result.  It will also
+            // be returned if the activity failed to launch.
+            if (resultCode == RESULT_CANCELED) {
+                text.append("(cancelled)");
+
+            // Our protocol with the sending activity is that it will send
+            // text in 'data' as its result.
+            } else {
+                text.append("(okay ");
+                text.append(Integer.toString(resultCode));
+                text.append(") ");
+                if (data != null) {
+                    text.append(data.getAction());
+                }
+            }
+
+            text.append("\n");
+        }
+    }
+
+    // Definition of the one requestCode we use for receiving resuls.
+    static final private int GET_CODE = 0;
+
+    private OnClickListener mGetListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Start the activity whose result we want to retrieve.  The
+            // result will come back with request code GET_CODE.
+            Intent intent = new Intent(ReceiveResult.this, SendResult.class);
+            startActivityForResult(intent, GET_CODE);
+        }
+    };
+
+    private TextView mResults;
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RedirectEnter.java b/samples/ApiDemos/src/com/example/android/apis/app/RedirectEnter.java
new file mode 100644
index 0000000..3a3e6f2
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RedirectEnter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+
+/**
+ * Entry into our redirection example, describing what will happen.
+ */
+public class RedirectEnter extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.redirect_enter);
+
+        // Watch for button clicks.
+        Button goButton = (Button)findViewById(R.id.go);
+        goButton.setOnClickListener(mGoListener);
+    }
+
+    private OnClickListener mGoListener = new OnClickListener()
+    {
+        public void onClick(View v)
+        {
+            // Here we start up the main entry point of our redirection
+            // example.
+            Intent intent = new Intent(RedirectEnter.this, RedirectMain.class);
+            startActivity(intent);
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java b/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
new file mode 100644
index 0000000..982317c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Sub-activity that is executed by the redirection example when input is needed
+ * from the user.
+ */
+public class RedirectGetter extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.redirect_getter);
+
+        // Watch for button clicks.
+        Button applyButton = (Button)findViewById(R.id.apply);
+        applyButton.setOnClickListener(mApplyListener);
+
+        // The text being set.
+        mText = (TextView)findViewById(R.id.text);
+    }
+
+    private final boolean loadPrefs()
+    {
+        // Retrieve the current redirect values.
+        // NOTE: because this preference is shared between multiple
+        // activities, you must be careful about when you read or write
+        // it in order to keep from stepping on yourself.
+        SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
+
+        mTextPref = preferences.getString("text", null);
+        if (mTextPref != null) {
+            mText.setText(mTextPref);
+            return true;
+        }
+
+        return false;
+    }
+
+    private OnClickListener mApplyListener = new OnClickListener()
+    {
+        public void onClick(View v)
+        {
+            SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
+            SharedPreferences.Editor editor = preferences.edit();
+            editor.putString("text", mText.getText().toString());
+
+            if (editor.commit()) {
+                setResult(RESULT_OK);
+            }
+
+            finish();
+        }
+    };
+
+    private String mTextPref;
+    TextView mText;
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RedirectMain.java b/samples/ApiDemos/src/com/example/android/apis/app/RedirectMain.java
new file mode 100644
index 0000000..6d01ff0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RedirectMain.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Entry into our redirection example, describing what will happen.
+ */
+public class RedirectMain extends Activity {
+    static final int INIT_TEXT_REQUEST = 0;
+    static final int NEW_TEXT_REQUEST = 1;
+
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.redirect_main);
+
+        // Watch for button clicks.
+        Button clearButton = (Button)findViewById(R.id.clear);
+        clearButton.setOnClickListener(mClearListener);
+        Button newButton = (Button)findViewById(R.id.newView);
+        newButton.setOnClickListener(mNewListener);
+
+        // Retrieve the current text preference.  If there is no text
+        // preference set, we need to get it from the user by invoking the
+        // activity that retrieves it.  To do this cleanly, we will
+        // temporarily hide our own activity so it is not displayed until the
+        // result is returned.
+        if (!loadPrefs()) {
+            Intent intent = new Intent(this, RedirectGetter.class);
+            startActivityForResult(intent, INIT_TEXT_REQUEST);
+        }
+    }
+
+    @Override
+	protected void onActivityResult(int requestCode, int resultCode,
+		Intent data) {
+        if (requestCode == INIT_TEXT_REQUEST) {
+
+            // If the request was cancelled, then we are cancelled as well.
+            if (resultCode == RESULT_CANCELED) {
+                finish();
+
+            // Otherwise, there now should be text...  reload the prefs,
+            // and show our UI.  (Optionally we could verify that the text
+            // is now set and exit if it isn't.)
+            } else {
+                loadPrefs();
+            }
+
+        } else if (requestCode == NEW_TEXT_REQUEST) {
+
+            // In this case we are just changing the text, so if it was
+            // cancelled then we can leave things as-is.
+            if (resultCode != RESULT_CANCELED) {
+                loadPrefs();
+            }
+
+        }
+    }
+
+    private final boolean loadPrefs() {
+        // Retrieve the current redirect values.
+        // NOTE: because this preference is shared between multiple
+        // activities, you must be careful about when you read or write
+        // it in order to keep from stepping on yourself.
+        SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
+
+        mTextPref = preferences.getString("text", null);
+        if (mTextPref != null) {
+            TextView text = (TextView)findViewById(R.id.text);
+            text.setText(mTextPref);
+            return true;
+        }
+
+        return false;
+    }
+
+    private OnClickListener mClearListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Erase the preferences and exit!
+            SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
+            preferences.edit().remove("text").commit();
+            finish();
+        }
+    };
+
+    private OnClickListener mNewListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Retrieve new text preferences.
+            Intent intent = new Intent(RedirectMain.this, RedirectGetter.class);
+            startActivityForResult(intent, NEW_TEXT_REQUEST);
+        }
+    };
+
+    private String mTextPref;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
new file mode 100644
index 0000000..c0debbc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.widget.Toast;
+
+import java.util.HashMap;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * This is an example of implementing an application service that runs in a
+ * different process than the application.  Because it can be in another
+ * process, we must use IPC to interact with it.  The
+ * {@link RemoteServiceController} and {@link RemoteServiceBinding} classes
+ * show how to interact with the service.
+ */
+public class RemoteService extends Service {
+    /**
+     * This is a list of callbacks that have been registered with the
+     * service.  Note that this is package scoped (instead of private) so
+     * that it can be accessed more efficiently from inner classes.
+     */
+    final RemoteCallbackList<IRemoteServiceCallback> mCallbacks
+            = new RemoteCallbackList<IRemoteServiceCallback>();
+    
+    int mValue = 0;
+    NotificationManager mNM;
+    
+    @Override
+    public void onCreate() {
+        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // Display a notification about us starting.
+        showNotification();
+        
+        // While this service is running, it will continually increment a
+        // number.  Send the first message that is used to perform the
+        // increment.
+        mHandler.sendEmptyMessage(REPORT_MSG);
+    }
+
+    @Override
+    public void onDestroy() {
+        // Cancel the persistent notification.
+        mNM.cancel(R.string.remote_service_started);
+
+        // Tell the user we stopped.
+        Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
+        
+        // Unregister all callbacks.
+        mCallbacks.kill();
+        
+        // Remove the next pending message to increment the counter, stopping
+        // the increment loop.
+        mHandler.removeMessages(REPORT_MSG);
+    }
+    
+// BEGIN_INCLUDE(exposing_a_service)
+    @Override
+    public IBinder onBind(Intent intent) {
+        // Select the interface to return.  If your service only implements
+        // a single interface, you can just return it here without checking
+        // the Intent.
+        if (IRemoteService.class.getName().equals(intent.getAction())) {
+            return mBinder;
+        }
+        if (ISecondary.class.getName().equals(intent.getAction())) {
+            return mSecondaryBinder;
+        }
+        return null;
+    }
+
+    /**
+     * The IRemoteInterface is defined through IDL
+     */
+    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+        public void registerCallback(IRemoteServiceCallback cb) {
+            if (cb != null) mCallbacks.register(cb);
+        }
+        public void unregisterCallback(IRemoteServiceCallback cb) {
+            if (cb != null) mCallbacks.unregister(cb);
+        }
+    };
+
+    /**
+     * A secondary interface to the service.
+     */
+    private final ISecondary.Stub mSecondaryBinder = new ISecondary.Stub() {
+        public int getPid() {
+            return Process.myPid();
+        }
+        public void basicTypes(int anInt, long aLong, boolean aBoolean,
+                float aFloat, double aDouble, String aString) {
+        }
+    };
+// END_INCLUDE(exposing_a_service)
+    
+    private static final int REPORT_MSG = 1;
+    
+    /**
+     * Our Handler used to execute operations on the main thread.  This is used
+     * to schedule increments of our value.
+     */
+    private final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                
+                // It is time to bump the value!
+                case REPORT_MSG: {
+                    // Up it goes.
+                    int value = ++mValue;
+                    
+                    // Broadcast to all clients the new value.
+                    final int N = mCallbacks.beginBroadcast();
+                    for (int i=0; i<N; i++) {
+                        try {
+                            mCallbacks.getBroadcastItem(i).valueChanged(value);
+                        } catch (RemoteException e) {
+                            // The RemoteCallbackList will take care of removing
+                            // the dead object for us.
+                        }
+                    }
+                    mCallbacks.finishBroadcast();
+                    
+                    // Repeat every 1 second.
+                    sendMessageDelayed(obtainMessage(REPORT_MSG), 1*1000);
+                } break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    };
+
+    /**
+     * Show a notification while this service is running.
+     */
+    private void showNotification() {
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(R.string.remote_service_started);
+
+        // Set the icon, scrolling text and timestamp
+        Notification notification = new Notification(R.drawable.stat_sample, text,
+                System.currentTimeMillis());
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, LocalServiceController.class), 0);
+
+        // Set the info for the views that show in the notification panel.
+        notification.setLatestEventInfo(this, getText(R.string.remote_service_label),
+                       text, contentIntent);
+
+        // Send the notification.
+        // We use a string id because it is a unique number.  We use it later to cancel.
+        mNM.notify(R.string.remote_service_started, notification);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceBinding.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceBinding.java
new file mode 100644
index 0000000..f9ad4e5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceBinding.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+// BEGIN_INCLUDE(exposing_a_service)
+public class RemoteServiceBinding extends Activity {
+    /** The primary interface we will be calling on the service. */
+    IRemoteService mService = null;
+    /** Another interface we use on the service. */
+    ISecondary mSecondaryService = null;
+    
+    Button mKillButton;
+    TextView mCallbackText;
+
+    private boolean mIsBound;
+
+    /**
+     * Standard initialization of this activity.  Set up the UI, then wait
+     * for the user to poke it before doing anything.
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.remote_service_binding);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.bind);
+        button.setOnClickListener(mBindListener);
+        button = (Button)findViewById(R.id.unbind);
+        button.setOnClickListener(mUnbindListener);
+        mKillButton = (Button)findViewById(R.id.kill);
+        mKillButton.setOnClickListener(mKillListener);
+        mKillButton.setEnabled(false);
+        
+        mCallbackText = (TextView)findViewById(R.id.callback);
+        mCallbackText.setText("Not attached.");
+    }
+
+    /**
+     * Class for interacting with the main interface of the service.
+     */
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className,
+                IBinder service) {
+            // This is called when the connection with the service has been
+            // established, giving us the service object we can use to
+            // interact with the service.  We are communicating with our
+            // service through an IDL interface, so get a client-side
+            // representation of that from the raw service object.
+            mService = IRemoteService.Stub.asInterface(service);
+            mKillButton.setEnabled(true);
+            mCallbackText.setText("Attached.");
+
+            // We want to monitor the service for as long as we are
+            // connected to it.
+            try {
+                mService.registerCallback(mCallback);
+            } catch (RemoteException e) {
+                // In this case the service has crashed before we could even
+                // do anything with it; we can count on soon being
+                // disconnected (and then reconnected if it can be restarted)
+                // so there is no need to do anything here.
+            }
+            
+            // As part of the sample, tell the user what happened.
+            Toast.makeText(RemoteServiceBinding.this, R.string.remote_service_connected,
+                    Toast.LENGTH_SHORT).show();
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            // This is called when the connection with the service has been
+            // unexpectedly disconnected -- that is, its process crashed.
+            mService = null;
+            mKillButton.setEnabled(false);
+            mCallbackText.setText("Disconnected.");
+
+            // As part of the sample, tell the user what happened.
+            Toast.makeText(RemoteServiceBinding.this, R.string.remote_service_disconnected,
+                    Toast.LENGTH_SHORT).show();
+        }
+    };
+
+    /**
+     * Class for interacting with the secondary interface of the service.
+     */
+    private ServiceConnection mSecondaryConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className,
+                IBinder service) {
+            // Connecting to a secondary interface is the same as any
+            // other interface.
+            mSecondaryService = ISecondary.Stub.asInterface(service);
+            mKillButton.setEnabled(true);
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            mSecondaryService = null;
+            mKillButton.setEnabled(false);
+        }
+    };
+
+    private OnClickListener mBindListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Establish a couple connections with the service, binding
+            // by interface names.  This allows other applications to be
+            // installed that replace the remote service by implementing
+            // the same interface.
+            bindService(new Intent(IRemoteService.class.getName()),
+                    mConnection, Context.BIND_AUTO_CREATE);
+            bindService(new Intent(ISecondary.class.getName()),
+                    mSecondaryConnection, Context.BIND_AUTO_CREATE);
+            mIsBound = true;
+            mCallbackText.setText("Binding.");
+        }
+    };
+
+    private OnClickListener mUnbindListener = new OnClickListener() {
+        public void onClick(View v) {
+            if (mIsBound) {
+                // If we have received the service, and hence registered with
+                // it, then now is the time to unregister.
+                if (mService != null) {
+                    try {
+                        mService.unregisterCallback(mCallback);
+                    } catch (RemoteException e) {
+                        // There is nothing special we need to do if the service
+                        // has crashed.
+                    }
+                }
+                
+                // Detach our existing connection.
+                unbindService(mConnection);
+                unbindService(mSecondaryConnection);
+                mKillButton.setEnabled(false);
+                mIsBound = false;
+                mCallbackText.setText("Unbinding.");
+            }
+        }
+    };
+
+    private OnClickListener mKillListener = new OnClickListener() {
+        public void onClick(View v) {
+            // To kill the process hosting our service, we need to know its
+            // PID.  Conveniently our service has a call that will return
+            // to us that information.
+            if (mSecondaryService != null) {
+                try {
+                    int pid = mSecondaryService.getPid();
+                    // Note that, though this API allows us to request to
+                    // kill any process based on its PID, the kernel will
+                    // still impose standard restrictions on which PIDs you
+                    // are actually able to kill.  Typically this means only
+                    // the process running your application and any additional
+                    // processes created by that app as shown here; packages
+                    // sharing a common UID will also be able to kill each
+                    // other's processes.
+                    Process.killProcess(pid);
+                    mCallbackText.setText("Killed service process.");
+                } catch (RemoteException ex) {
+                    // Recover gracefully from the process hosting the
+                    // server dying.
+                    // Just for purposes of the sample, put up a notification.
+                    Toast.makeText(RemoteServiceBinding.this,
+                            R.string.remote_call_failed,
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        }
+    };
+    
+    // ----------------------------------------------------------------------
+    // Code showing how to deal with callbacks.
+    // ----------------------------------------------------------------------
+    
+    /**
+     * This implementation is used to receive callbacks from the remote
+     * service.
+     */
+    private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
+        /**
+         * This is called by the remote service regularly to tell us about
+         * new values.  Note that IPC calls are dispatched through a thread
+         * pool running in each process, so the code executing here will
+         * NOT be running in our main thread like most other things -- so,
+         * to update the UI, we need to use a Handler to hop over there.
+         */
+        public void valueChanged(int value) {
+            mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
+        }
+    };
+    
+    private static final int BUMP_MSG = 1;
+    
+    private Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case BUMP_MSG:
+                    mCallbackText.setText("Received from service: " + msg.arg1);
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+        
+    };
+}
+// END_INCLUDE(exposing_a_service)
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceController.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceController.java
new file mode 100644
index 0000000..681d411
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class RemoteServiceController extends Activity {
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.remote_service_controller);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.start);
+        button.setOnClickListener(mStartListener);
+        button = (Button)findViewById(R.id.stop);
+        button.setOnClickListener(mStopListener);
+    }
+
+    private OnClickListener mStartListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Make sure the service is started.  It will continue running
+            // until someone calls stopService().
+            // We use an action code here, instead of explictly supplying
+            // the component name, so that other packages can replace
+            // the service.
+            startService(new Intent(
+                    "com.example.android.apis.app.REMOTE_SERVICE"));
+        }
+    };
+
+    private OnClickListener mStopListener = new OnClickListener() {
+        public void onClick(View v) {
+            // Cancel a previous call to startService().  Note that the
+            // service will not actually stop at this point if there are
+            // still bound clients.
+            stopService(new Intent(
+                    "com.example.android.apis.app.REMOTE_SERVICE"));
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReorderFour.java b/samples/ApiDemos/src/com/example/android/apis/app/ReorderFour.java
new file mode 100644
index 0000000..cdff538
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReorderFour.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ReorderFour extends Activity {
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        
+        setContentView(R.layout.reorder_four);
+        
+        Button twoButton = (Button) findViewById(R.id.reorder_second_to_front);
+        twoButton.setOnClickListener(mClickListener);
+    }
+
+    private final OnClickListener mClickListener = new OnClickListener() {
+        public void onClick(View v) {
+            Intent intent = new Intent(ReorderFour.this, ReorderTwo.class);
+            intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+            startActivity(intent);
+        }
+    };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReorderOnLaunch.java b/samples/ApiDemos/src/com/example/android/apis/app/ReorderOnLaunch.java
new file mode 100644
index 0000000..5856184
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReorderOnLaunch.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ReorderOnLaunch extends Activity {
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        
+        setContentView(R.layout.reorder_on_launch);
+        
+        Button twoButton = (Button) findViewById(R.id.reorder_launch_two);
+        twoButton.setOnClickListener(mClickListener);
+    }
+
+    private final OnClickListener mClickListener = new OnClickListener() {
+        public void onClick(View v) {
+            startActivity(new Intent(ReorderOnLaunch.this, ReorderTwo.class));
+        }
+    };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReorderThree.java b/samples/ApiDemos/src/com/example/android/apis/app/ReorderThree.java
new file mode 100644
index 0000000..7f725a6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReorderThree.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ReorderThree extends Activity {
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        
+        setContentView(R.layout.reorder_three);
+        
+        Button twoButton = (Button) findViewById(R.id.reorder_launch_four);
+        twoButton.setOnClickListener(mClickListener);
+    }
+
+    private final OnClickListener mClickListener = new OnClickListener() {
+        public void onClick(View v) {
+            startActivity(new Intent(ReorderThree.this, ReorderFour.class));
+        }
+    };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReorderTwo.java b/samples/ApiDemos/src/com/example/android/apis/app/ReorderTwo.java
new file mode 100644
index 0000000..a1521d0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReorderTwo.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ReorderTwo extends Activity {
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        
+        setContentView(R.layout.reorder_two);
+        
+        Button twoButton = (Button) findViewById(R.id.reorder_launch_three);
+        twoButton.setOnClickListener(mClickListener);
+    }
+
+    private final OnClickListener mClickListener = new OnClickListener() {
+        public void onClick(View v) {
+            startActivity(new Intent(ReorderTwo.this, ReorderThree.class));
+        }
+    };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RepeatingAlarm.java b/samples/ApiDemos/src/com/example/android/apis/app/RepeatingAlarm.java
new file mode 100644
index 0000000..0027983
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RepeatingAlarm.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.widget.Toast;
+
+/**
+ * This is an example of implement an {@link BroadcastReceiver} for an alarm that
+ * should occur once.
+ */
+public class RepeatingAlarm extends BroadcastReceiver
+{
+    @Override
+    public void onReceive(Context context, Intent intent)
+    {
+        Toast.makeText(context, R.string.repeating_received, Toast.LENGTH_SHORT).show();
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SaveRestoreState.java b/samples/ApiDemos/src/com/example/android/apis/app/SaveRestoreState.java
new file mode 100644
index 0000000..bddedf3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SaveRestoreState.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * <p>Demonstrates required behavior of saving and restoring dynamic activity
+ * state, so that an activity will restart with the correct state if it is
+ * stopped by the system.</p>
+ *
+ * <p>In general, any activity that has been paused may be stopped by the system
+ * at any time if it needs more resources for the currently running activity.
+ * To handle this, before being paused the
+ * {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} method is called before
+ * an activity is paused, allowing it to supply its current state.  If that
+ * activity then needs to be stopped, upon restarting it will receive its
+ * last saved state in
+ * {@link android.app.Activity#onCreate}.</p>
+ * <p>In this example we are currently saving and restoring the state of the
+ * top text editor, but not of the bottom text editor.  You can see the difference
+ * by editing the two text fields, then going to a couple different
+ * applications while the demo is running and then returning back to it.  The
+ * system takes care of saving a view's state as long as an id has been
+ * assigned to the view, so we assign an ID to the view being saved but not
+ * one to the view that isn't being saved.</p>
+ * <h4>Demo</h4>
+ * App/Activity/Save &amp; Restore State
+ * <h4>Source files</h4>
+ * <table class="LinkTable">
+        <tr>
+            <td class="LinkColumn">src/com.example.android.apis/app/SaveRestoreState.java</td>
+            <td class="DescrColumn">The Save/Restore Screen implementation</td>
+        </tr>
+        <tr>
+            <td class="LinkColumn">/res/any/layout/save_restore_state.xml</td>
+            <td class="DescrColumn">Defines contents of the screen</td>
+        </tr>
+</table>
+ */
+public class SaveRestoreState extends Activity
+{
+    /**
+     * Initialization of the Activity after it is first created.  Here we use
+     * {@link android.app.Activity#setContentView setContentView()} to set up
+     * the Activity's content, and retrieve the EditText widget whose state we
+     * will save/restore.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/save_restore_state.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.save_restore_state);
+
+        // Set message to be appropriate for this screen.
+        ((TextView)findViewById(R.id.msg)).setText(R.string.save_restore_msg);
+    }
+
+    /**
+     * Retrieve the text that is currently in the "saved" editor.
+     */
+    CharSequence getSavedText() {
+        return ((EditText)findViewById(R.id.saved)).getText();
+    }
+
+    /**
+     * Change the text that is currently in the "saved" editor.
+     */
+    void setSavedText(CharSequence text) {
+        ((EditText)findViewById(R.id.saved)).setText(text);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SearchInvoke.java b/samples/ApiDemos/src/com/example/android/apis/app/SearchInvoke.java
new file mode 100644
index 0000000..a8d350c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SearchInvoke.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.SearchManager;
+import android.os.Bundle;
+import android.provider.SearchRecentSuggestions;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+public class SearchInvoke extends Activity
+{  
+        // UI elements
+    Button mStartSearch;
+    Spinner mMenuMode;
+    EditText mQueryPrefill;
+    EditText mQueryAppData;
+    
+        // Menu mode spinner choices
+        // This list must match the list found in samples/ApiDemos/res/values/arrays.xml
+    final static int MENUMODE_SEARCH_KEY = 0;
+    final static int MENUMODE_MENU_ITEM = 1;
+    final static int MENUMODE_TYPE_TO_SEARCH = 2;
+    final static int MENUMODE_DISABLED = 3;
+    
+    /** 
+     * Called with the activity is first created.
+     * 
+     *  We aren't doing anything special in this implementation, other than
+     *  the usual activity setup code. 
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Inflate our UI from its XML layout description.
+        setContentView(R.layout.search_invoke);
+        
+        // Get display items for later interaction
+        mStartSearch = (Button) findViewById(R.id.btn_start_search);
+        mMenuMode = (Spinner) findViewById(R.id.spinner_menu_mode);
+        mQueryPrefill = (EditText) findViewById(R.id.txt_query_prefill);
+        mQueryAppData = (EditText) findViewById(R.id.txt_query_appdata);
+        
+        // Populate items
+        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
+                            this, R.array.search_menuModes, android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mMenuMode.setAdapter(adapter);
+        
+        // Create listener for the menu mode dropdown.  We use this to demonstrate control
+        // of the default keys handler in every Activity.  More typically, you will simply set
+        // the default key mode in your activity's onCreate() handler.
+        mMenuMode.setOnItemSelectedListener(
+            new OnItemSelectedListener() {
+                public void onItemSelected(
+                        AdapterView<?> parent, View view, int position, long id) {
+                    if (position == MENUMODE_TYPE_TO_SEARCH) {
+                        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
+                    } else {
+                        setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
+                    }
+                }
+
+                public void onNothingSelected(AdapterView<?> parent) {
+                    setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
+                }
+            });
+        
+        // Attach actions to buttons
+        mStartSearch.setOnClickListener(
+            new OnClickListener() {
+                public void onClick(View v) {
+                    onSearchRequested();
+                }
+            });
+    }
+    
+    /** 
+     * Called when your activity's options menu needs to be updated. 
+     */
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        MenuItem item;
+        
+            // first, get rid of our menus (if any)
+        menu.removeItem(0);
+        menu.removeItem(1);
+        
+            // next, add back item(s) based on current menu mode
+        switch (mMenuMode.getSelectedItemPosition())
+        {
+        case MENUMODE_SEARCH_KEY:
+            item = menu.add( 0, 0, 0, "(Search Key)");
+            break;
+            
+        case MENUMODE_MENU_ITEM:
+            item = menu.add( 0, 0, 0, "Search");
+            item.setAlphabeticShortcut(SearchManager.MENU_KEY);
+            break;
+            
+        case MENUMODE_TYPE_TO_SEARCH:
+            item = menu.add( 0, 0, 0, "(Type-To-Search)");
+            break;
+            
+        case MENUMODE_DISABLED:
+            item = menu.add( 0, 0, 0, "(Disabled)");
+            break;
+        }
+        
+        item = menu.add(0, 1, 0, "Clear History");
+        return true;
+    }
+    
+    /** Handle the menu item selections */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case 0:
+            switch (mMenuMode.getSelectedItemPosition()) {
+            case MENUMODE_SEARCH_KEY:
+                new AlertDialog.Builder(this)
+                    .setMessage("To invoke search, dismiss this dialog and press the search key" +
+                                " (F5 on the simulator).")
+                    .setPositiveButton("OK", null)
+                    .show();
+                break;
+                
+            case MENUMODE_MENU_ITEM:
+                onSearchRequested();
+                break;
+                
+            case MENUMODE_TYPE_TO_SEARCH:
+                new AlertDialog.Builder(this)
+                    .setMessage("To invoke search, dismiss this dialog and start typing.")
+                    .setPositiveButton("OK", null)
+                    .show();
+                break;
+                
+            case MENUMODE_DISABLED:
+                new AlertDialog.Builder(this)
+                    .setMessage("You have disabled search.")
+                    .setPositiveButton("OK", null)
+                    .show();
+                break;
+            }
+            break;
+        case 1:
+            clearSearchHistory();
+            break;
+        }
+    
+         return super.onOptionsItemSelected(item);
+    }
+    
+    /**
+     * This hook is called when the user signals the desire to start a search.
+     * 
+     * By overriding this hook we can insert local or context-specific data.
+     * 
+     * @return Returns true if search launched, false if activity blocks it
+     */
+    @Override
+    public boolean onSearchRequested() {
+        // If your application absolutely must disable search, do it here.
+        if (mMenuMode.getSelectedItemPosition() == MENUMODE_DISABLED) {
+            return false;
+        }
+        
+        // It's possible to prefill the query string before launching the search
+        // UI.  For this demo, we simply copy it from the user input field.
+        // For most applications, you can simply pass null to startSearch() to
+        // open the UI with an empty query string.
+        final String queryPrefill = mQueryPrefill.getText().toString();
+        
+        // Next, set up a bundle to send context-specific search data (if any)
+        // The bundle can contain any number of elements, using any number of keys;
+        // For this Api Demo we copy a string from the user input field, and store
+        // it in the bundle as a string with the key "demo_key".
+        // For most applications, you can simply pass null to startSearch().
+        Bundle appDataBundle = null;
+        final String queryAppDataString = mQueryAppData.getText().toString();
+        if (queryAppDataString != null) {
+            appDataBundle = new Bundle();
+            appDataBundle.putString("demo_key", queryAppDataString);
+        }
+        
+        // Now call the Activity member function that invokes the Search Manager UI.
+        startSearch(queryPrefill, false, appDataBundle, false); 
+        
+        // Returning true indicates that we did launch the search, instead of blocking it.
+        return true;
+    }
+    
+    /**
+     * Any application that implements search suggestions based on previous actions (such as
+     * recent queries, page/items viewed, etc.) should provide a way for the user to clear the
+     * history.  This gives the user a measure of privacy, if they do not wish for their recent
+     * searches to be replayed by other users of the device (via suggestions).
+     * 
+     * This example shows how to clear the search history for apps that use 
+     * android.provider.SearchRecentSuggestions.  If you have developed a custom suggestions
+     * provider, you'll need to provide a similar API for clearing history.
+     * 
+     * In this sample app we call this method from a "Clear History" menu item.  You could also 
+     * implement the UI in your preferences, or any other logical place in your UI.
+     */
+    private void clearSearchHistory() {
+        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, 
+                SearchSuggestionSampleProvider.AUTHORITY, SearchSuggestionSampleProvider.MODE);
+        suggestions.clearHistory();
+    }
+    
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SearchQueryResults.java b/samples/ApiDemos/src/com/example/android/apis/app/SearchQueryResults.java
new file mode 100644
index 0000000..668ad57
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SearchQueryResults.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.SearchRecentSuggestions;
+import android.widget.TextView;
+
+public class SearchQueryResults extends Activity
+{  
+        // UI elements
+    TextView mQueryText;
+    TextView mAppDataText;
+    TextView mDeliveredByText;
+    
+    /** Called with the activity is first created.
+    * 
+    *  After the typical activity setup code, we check to see if we were launched
+    *  with the ACTION_SEARCH intent, and if so, we handle it.
+    */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Inflate our UI from its XML layout description.
+        setContentView(R.layout.search_query_results);
+        
+        // Get active display items for later updates
+        mQueryText = (TextView) findViewById(R.id.txt_query);
+        mAppDataText = (TextView) findViewById(R.id.txt_appdata);
+        mDeliveredByText = (TextView) findViewById(R.id.txt_deliveredby);
+        
+        // get and process search query here
+        final Intent queryIntent = getIntent();
+        final String queryAction = queryIntent.getAction();
+        if (Intent.ACTION_SEARCH.equals(queryAction)) {
+            doSearchQuery(queryIntent, "onCreate()");
+        }
+        else {
+            mDeliveredByText.setText("onCreate(), but no ACTION_SEARCH intent");
+        }
+    }
+    
+    /** 
+     * Called when new intent is delivered.
+     *
+     * This is where we check the incoming intent for a query string.
+     * 
+     * @param newIntent The intent used to restart this activity
+     */
+    @Override
+    public void onNewIntent(final Intent newIntent) {
+        super.onNewIntent(newIntent);
+        
+        // get and process search query here
+        final Intent queryIntent = getIntent();
+        final String queryAction = queryIntent.getAction();
+        if (Intent.ACTION_SEARCH.equals(queryAction)) {
+            doSearchQuery(queryIntent, "onNewIntent()");
+        }
+        else {
+            mDeliveredByText.setText("onNewIntent(), but no ACTION_SEARCH intent");
+        }
+    }
+    
+    /**
+     * Generic search handler.
+     * 
+     * In a "real" application, you would use the query string to select results from
+     * your data source, and present a list of those results to the user.
+     */
+    private void doSearchQuery(final Intent queryIntent, final String entryPoint) {
+        
+        // The search query is provided as an "extra" string in the query intent
+        final String queryString = queryIntent.getStringExtra(SearchManager.QUERY);
+        mQueryText.setText(queryString);
+        
+        // Record the query string in the recent queries suggestions provider.
+        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, 
+                SearchSuggestionSampleProvider.AUTHORITY, SearchSuggestionSampleProvider.MODE);
+        suggestions.saveRecentQuery(queryString, null);
+        
+        // If your application provides context data for its searches, 
+        // you will receive it as an "extra" bundle in the query intent. 
+        // The bundle can contain any number of elements, using any number of keys;
+        // For this Api Demo we're just using a single string, stored using "demo key".
+        final Bundle appData = queryIntent.getBundleExtra(SearchManager.APP_DATA);
+        if (appData == null) {
+            mAppDataText.setText("<no app data bundle>");
+        }
+        if (appData != null) {
+            String testStr = appData.getString("demo_key");
+            mAppDataText.setText((testStr == null) ? "<no app data>" : testStr);
+        }
+        
+        // Report the method by which we were called.
+        mDeliveredByText.setText(entryPoint);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SearchSuggestionSampleProvider.java b/samples/ApiDemos/src/com/example/android/apis/app/SearchSuggestionSampleProvider.java
new file mode 100644
index 0000000..4baccd0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SearchSuggestionSampleProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.content.SearchRecentSuggestionsProvider;
+
+/**
+ * To create a search suggestions provider using the built-in recent queries mode, 
+ * simply extend SearchRecentSuggestionsProvider as shown here, and configure with
+ * a unique authority and the mode you with to use.  For more information, see
+ * {@link android.content.SearchRecentSuggestionsProvider}.
+ */
+public class SearchSuggestionSampleProvider extends SearchRecentSuggestionsProvider {
+    
+    /**
+     * This is the provider authority identifier.  The same string must appear in your
+     * Manifest file, and any time you instantiate a 
+     * {@link android.provider.SearchRecentSuggestions} helper class. 
+     */
+    final static String AUTHORITY = "com.example.android.apis.SuggestionProvider";
+    /**
+     * These flags determine the operating mode of the suggestions provider.  This value should 
+     * not change from run to run, because when it does change, your suggestions database may 
+     * be wiped.
+     */
+    final static int MODE = DATABASE_MODE_QUERIES;
+    
+    /**
+     * The main job of the constructor is to call {@link #setupSuggestions(String, int)} with the
+     * appropriate configuration values.
+     */
+    public SearchSuggestionSampleProvider() {
+        super();
+        setupSuggestions(AUTHORITY, MODE);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SendResult.java b/samples/ApiDemos/src/com/example/android/apis/app/SendResult.java
new file mode 100644
index 0000000..1171eea
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SendResult.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+
+/**
+ * Example of receiving a result from another activity.
+ */
+public class SendResult extends Activity
+{
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/hello_world.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.send_result);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.corky);
+        button.setOnClickListener(mCorkyListener);
+        button = (Button)findViewById(R.id.violet);
+        button.setOnClickListener(mVioletListener);
+    }
+
+    private OnClickListener mCorkyListener = new OnClickListener()
+    {
+        public void onClick(View v)
+        {
+            // To send a result, simply call setResult() before your
+            // activity is finished.
+            setResult(RESULT_OK, (new Intent()).setAction("Corky!"));
+            finish();
+        }
+    };
+
+    private OnClickListener mVioletListener = new OnClickListener()
+    {
+        public void onClick(View v)
+        {
+            // To send a result, simply call setResult() before your
+            // activity is finished.
+            setResult(RESULT_OK, (new Intent()).setAction("Violet!"));
+            finish();
+        }
+    };
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
new file mode 100644
index 0000000..5e16158
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.example.android.apis.R;
+
+/**
+ * This is an example of implementing an application service that runs locally
+ * in the same process as the application.  The {@link ServiceStartArgumentsController}
+ * class shows how to interact with the service. 
+ *
+ * <p>Notice the use of the {@link NotificationManager} when interesting things
+ * happen in the service.  This is generally how background services should
+ * interact with the user, rather than doing something more disruptive such as
+ * calling startActivity().
+ */
+public class ServiceStartArguments extends Service
+{
+    private NotificationManager mNM;
+    private Intent mInvokeIntent;
+    private volatile Looper mServiceLooper;
+    private volatile ServiceHandler mServiceHandler;
+    
+    private final class ServiceHandler extends Handler {
+        public ServiceHandler(Looper looper) {
+            super(looper);
+        }
+        
+        @Override
+        public void handleMessage(Message msg)
+        {
+            Bundle arguments = (Bundle)msg.obj;
+            String txt = getResources()
+                    .getString(R.string.service_arguments_started);
+            txt = txt + arguments.getString("name");
+        
+            Log.i("ServiceStartArguments", "Message: " + msg + ", " + txt);
+        
+            showNotification();
+        
+        // Normally we would do some work here...  for our sample, we will
+        // just sleep for 10 seconds.
+            long endTime = System.currentTimeMillis() + 5*1000;
+            while (System.currentTimeMillis() < endTime) {
+                synchronized (this) {
+                    try {
+                        wait(endTime - System.currentTimeMillis());
+                    } catch (Exception e) {
+                    }
+                }
+            }
+        
+            Log.i("ServiceStartArguments", "Done with #" + msg.arg1);
+            stopSelf(msg.arg1);
+        }
+
+    };
+    
+    @Override
+    public void onCreate() {
+        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+
+        // This is who should be launched if the user selects our persistent
+        // notification.
+        mInvokeIntent = new Intent(this, ServiceStartArgumentsController.class);
+
+        // Start up the thread running the service.  Note that we create a
+        // separate thread because the service normally runs in the process's
+        // main thread, which we don't want to block.
+        HandlerThread thread = new HandlerThread("ServiceStartArguments");
+        thread.start();
+        
+        mServiceLooper = thread.getLooper();
+        mServiceHandler = new ServiceHandler(mServiceLooper);
+    }
+
+    @Override
+    public void onStart(Intent intent, int startId) {
+        Log.i("ServiceStartArguments",
+                "Starting #" + startId + ": " + intent.getExtras());
+        Message msg = mServiceHandler.obtainMessage();
+        msg.arg1 = startId;
+        msg.obj = intent.getExtras();
+        mServiceHandler.sendMessage(msg);
+        Log.i("ServiceStartArguments", "Sending: " + msg);
+    }
+
+    @Override
+    public void onDestroy() {
+        mServiceLooper.quit();
+
+        // Cancel the persistent notification.
+        mNM.cancel(R.string.service_arguments_started);
+
+        // Tell the user we stopped.
+        Toast.makeText(ServiceStartArguments.this, R.string.service_arguments_stopped,
+                Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    /**
+     * Show a notification while this service is running.
+     */
+    private void showNotification() {
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(R.string.service_arguments_started);
+
+        // Set the icon, scrolling text and timestamp
+        Notification notification = new Notification(R.drawable.stat_sample, text,
+                System.currentTimeMillis());
+
+        // The PendingIntent to launch our activity if the user selects this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, AlarmService.class), 0);
+
+        // Set the info for the views that show in the notification panel.
+        notification.setLatestEventInfo(this, getText(R.string.service_start_arguments_label),
+                       text, contentIntent);
+
+        // Send the notification.
+        // We use a string id because it is a unique number.  We use it later to cancel.
+        mNM.notify(R.string.service_arguments_started, notification);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java
new file mode 100644
index 0000000..2c53ff4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.example.android.apis.R;
+
+import java.util.HashMap;
+
+/**
+ * Example of explicitly starting the {@link ServiceStartArguments}.
+ */
+public class ServiceStartArgumentsController extends Activity {
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.service_start_arguments_controller);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.start1);
+        button.setOnClickListener(mStart1Listener);
+        button = (Button)findViewById(R.id.start2);
+        button.setOnClickListener(mStart2Listener);
+        button = (Button)findViewById(R.id.start3);
+        button.setOnClickListener(mStart3Listener);
+    }
+
+    private OnClickListener mStart1Listener = new OnClickListener() {
+        public void onClick(View v) {
+            startService(new Intent(ServiceStartArgumentsController.this,
+                    ServiceStartArguments.class).putExtra("name", "One"));
+        }
+    };
+
+    private OnClickListener mStart2Listener = new OnClickListener() {
+        public void onClick(View v) {
+            startService(new Intent(ServiceStartArgumentsController.this,
+                    ServiceStartArguments.class).putExtra("name", "Two"));
+        }
+    };
+
+    private OnClickListener mStart3Listener = new OnClickListener() {
+        public void onClick(View v) {
+            startService(new Intent(ServiceStartArgumentsController.this,
+                    ServiceStartArguments.class).putExtra("name", "Three"));
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java b/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
new file mode 100644
index 0000000..97f6199
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.RemoteViews;
+
+/**
+ * Demonstrates adding notifications to the status bar
+ */
+public class StatusBarNotifications extends Activity {
+
+    private NotificationManager mNotificationManager;
+
+    // Use our layout id for a unique identifier
+    private static int MOOD_NOTIFICATIONS = R.layout.status_bar_notifications;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.status_bar_notifications);
+
+        Button button;
+
+        // Get the notification manager serivce.
+        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+
+        button = (Button) findViewById(R.id.happy);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMood(R.drawable.stat_happy, R.string.status_bar_notifications_happy_message,
+                        false);
+            }
+        });
+
+        button = (Button) findViewById(R.id.neutral);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMood(R.drawable.stat_neutral, R.string.status_bar_notifications_ok_message,
+                        false);
+            }
+        });
+
+        button = (Button) findViewById(R.id.sad);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMood(R.drawable.stat_sad, R.string.status_bar_notifications_sad_message, false);
+            }
+        });
+
+        button = (Button) findViewById(R.id.happyMarquee);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMood(R.drawable.stat_happy, R.string.status_bar_notifications_happy_message,
+                        true);
+            }
+        });
+
+        button = (Button) findViewById(R.id.neutralMarquee);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMood(R.drawable.stat_neutral, R.string.status_bar_notifications_ok_message, true);
+            }
+        });
+
+        button = (Button) findViewById(R.id.sadMarquee);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMood(R.drawable.stat_sad, R.string.status_bar_notifications_sad_message, true);
+            }
+        });
+
+        button = (Button) findViewById(R.id.happyViews);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMoodView(R.drawable.stat_happy, R.string.status_bar_notifications_happy_message);
+            }
+        });
+
+        button = (Button) findViewById(R.id.neutralViews);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMoodView(R.drawable.stat_neutral, R.string.status_bar_notifications_ok_message);
+            }
+        });
+
+        button = (Button) findViewById(R.id.sadViews);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setMoodView(R.drawable.stat_sad, R.string.status_bar_notifications_sad_message);
+            }
+        });
+        
+        button = (Button) findViewById(R.id.defaultSound);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setDefault(Notification.DEFAULT_SOUND);
+            }
+        });
+        
+        button = (Button) findViewById(R.id.defaultVibrate);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setDefault(Notification.DEFAULT_VIBRATE);
+            }
+        });
+        
+        button = (Button) findViewById(R.id.defaultAll);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                setDefault(Notification.DEFAULT_ALL);
+            }
+        });
+        
+        button = (Button) findViewById(R.id.clear);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                mNotificationManager.cancel(R.layout.status_bar_notifications);
+            }
+        });
+    }
+
+    private PendingIntent makeMoodIntent(int moodId) {
+        // The PendingIntent to launch our activity if the user selects this
+        // notification.  Note the use of FLAG_UPDATE_CURRENT so that if there
+        // is already an active matching pending intent, we will update its
+        // extras to be the ones passed in here.
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, NotificationDisplay.class)
+                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                        .putExtra("moodimg", moodId),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+        return contentIntent;
+    }
+    
+    private void setMood(int moodId, int textId, boolean showTicker) {
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(textId);
+
+        // choose the ticker text
+        String tickerText = showTicker ? getString(textId) : null;
+
+        // Set the icon, scrolling text and timestamp
+        Notification notification = new Notification(moodId, tickerText,
+                System.currentTimeMillis());
+
+        // Set the info for the views that show in the notification panel.
+        notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title),
+                       text, makeMoodIntent(moodId));
+
+        // Send the notification.
+        // We use a layout id because it is a unique number.  We use it later to cancel.
+        mNotificationManager.notify(R.layout.status_bar_notifications, notification);
+    }
+
+    private void setMoodView(int moodId, int textId) {
+        // Instead of the normal constructor, we're going to use the one with no args and fill
+        // in all of the data ourselves.  The normal one uses the default layout for notifications.
+        // You probably want that in most cases, but if you want to do something custom, you
+        // can set the contentView field to your own RemoteViews object.
+        Notification notif = new Notification();
+
+        // This is who should be launched if the user selects our notification.
+        notif.contentIntent = makeMoodIntent(moodId);
+
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(textId);
+        notif.tickerText = text;
+
+        // the icon for the status bar
+        notif.icon = moodId;
+
+        // our custom view
+        RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.status_bar_balloon);
+        contentView.setTextViewText(R.id.text, text);
+        contentView.setImageViewResource(R.id.icon, moodId);
+        notif.contentView = contentView;
+
+        // we use a string id because is a unique number.  we use it later to cancel the
+        // notification
+        mNotificationManager.notify(R.layout.status_bar_notifications, notif);
+    }
+    
+    private void setDefault(int defaults) {
+        
+        // This method sets the defaults on the notification before posting it.
+        
+        // This is who should be launched if the user selects our notification.
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, StatusBarNotifications.class), 0);
+
+        // In this sample, we'll use the same text for the ticker and the expanded notification
+        CharSequence text = getText(R.string.status_bar_notifications_happy_message);
+
+        final Notification notification = new Notification(
+                R.drawable.stat_happy,       // the icon for the status bar
+                text,                        // the text to display in the ticker
+                System.currentTimeMillis()); // the timestamp for the notification
+
+        notification.setLatestEventInfo(
+                this,                        // the context to use
+                getText(R.string.status_bar_notifications_mood_title),
+                                             // the title for the notification
+                text,                        // the details to display in the notification
+                contentIntent);              // the contentIntent (see above)
+
+        notification.defaults = defaults;
+        
+        mNotificationManager.notify(
+                   R.layout.status_bar_notifications, // we use a string id because it is a unique
+                                                      // number.  we use it later to cancel the
+                   notification);                     // notification
+    }    
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/TranslucentActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/TranslucentActivity.java
new file mode 100644
index 0000000..522fe13
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/TranslucentActivity.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * <h3>Translucent Activity</h3>
+ * 
+ * <p>This demonstrates the how to write an activity that is translucent,
+ * allowing windows underneath to show through.</p>
+ */
+public class TranslucentActivity extends Activity {
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+        
+        // See assets/res/any/layout/translucent_background.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.translucent_background);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/TranslucentBlurActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/TranslucentBlurActivity.java
new file mode 100644
index 0000000..dd88227
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/TranslucentBlurActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+
+/**
+ * <h3>Fancy Blur Activity</h3>
+ * 
+ * <p>This demonstrates the how to write an activity that is translucent,
+ * allowing windows underneath to show through, with a fancy blur
+ * compositing effect.</p>
+ */
+public class TranslucentBlurActivity extends Activity {
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+    protected void onCreate(Bundle icicle) {
+        // Be sure to call the super class.
+        super.onCreate(icicle);
+
+        // Have the system blur any windows behind this one.
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
+                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+        
+        // See assets/res/any/layout/translucent_background.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.translucent_background);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/VoiceRecognition.java b/samples/ApiDemos/src/com/example/android/apis/app/VoiceRecognition.java
new file mode 100644
index 0000000..a784e15
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/VoiceRecognition.java
@@ -0,0 +1,94 @@
+/* 
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+/**
+ * Sample code that invokes the speech recognition intent API.
+ */
+public class VoiceRecognition extends Activity implements OnClickListener {
+    
+    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
+    
+    private ListView mList;
+
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Inflate our UI from its XML layout description.
+        setContentView(R.layout.voice_recognition);
+
+        // Get display items for later interaction
+        Button speakButton = (Button) findViewById(R.id.btn_speak);
+        
+        mList = (ListView) findViewById(R.id.list);
+
+        // Attach actions to buttons
+        speakButton.setOnClickListener(this);
+    }
+
+    /**
+     * Handle the click on the start recognition button.
+     */
+    public void onClick(View v) {
+        if (v.getId() == R.id.btn_speak) {
+            startVoiceRecognitionActivity();
+        }
+    }
+
+    /**
+     * Fire an intent to start the speech recognition activity.
+     */
+    private void startVoiceRecognitionActivity() {
+        //TODO Get these values from constants
+        Intent intent = new Intent("android.speech.action.RECOGNIZE_SPEECH");
+        intent.putExtra("language_model", "free_form");
+        intent.putExtra("prompt", "Speech recognition demo");
+        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
+    }
+
+    /**
+     * Handle the results from the recognition activity.
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
+            //TODO get the value from a constant
+            ArrayList<String>matches = data.getStringArrayListExtra("results");
+            mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
+                    matches));
+        }
+
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/_index.html b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
new file mode 100644
index 0000000..8a768bb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
@@ -0,0 +1,145 @@
+
+<h3>Activity</h3>
+<dl>
+  <dt><a href="HelloWorld.html">Hello World</a></dt>
+  <dd>Demonstrates a basic screen activity.
+  <dl>
+  <dt>Code:
+  <dd> <a href="HelloWorld.html">HelloWorld.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/hello_world.html">
+  hello_world.xml</a>
+  </dl>
+  </dd>
+  <dt><a href="SaveRestoreState.html">Save &amp; Restore State</a></dt>
+  <dd>Demonstrates how an activity should save state when it is paused.</dd>
+
+  <dt><a href="PersistentState.html">Persistent State</a></dt>
+  <dd>Demonstrates how you can save and restore preferences, which are stored
+  even after the user closes the application. </dd>
+
+  <dt><a href="ReceiveResult.html">Receive Result</a></dt>
+  <dd>Demonstrates how an activity screen can return a result to the
+  activity that opened it. </dd>
+
+  <dt><a href="Forwarding.html">Forwarding</a></dt>
+  <dd>Demonstrates opening a new activity and removing the current activity
+  from the history stack, so that when the user later presses BACK they will
+  not see the intermediate activity.</dd>
+
+  <dt><a href="RedirectEnter.html">Redirection</a></dt>
+  <dd>Demonstrates how to save data to preferences and use it to determine
+  which activity to open next.</dd>
+
+  <dt><a href="TranslucentActivity.html">Translucent</a></dt>
+  <dd>Demonstrates how to make an activity with a transparent background. </dd>
+
+  <dt><a href="TranslucentFancyActivity.html">TranslucentFancy</a></dt>
+  <dd>Demonstrates how to make an activity with a transparent background with
+  a special effect (blur). </dd>
+</dl>
+
+<h3>Service</h3>
+<dl>
+  <dt><a href="LocalServiceController.html">Local Service Controller</a></dt>
+  <dd>Starts and stops the service class
+  <a href="LocalService.html">LocalService</a> that runs in the same
+  process as the activity, to demonstrate a service's
+  lifecycle when using {@link android.content.Context#startService
+  Context.startService} and {@link android.content.Context#stopService
+  Context.stopService}.</dd>
+
+  <dt><a href="LocalServiceBinding.html">Local Service Binding</a></dt>
+  <dd>Demonstrates binding to a service class
+  <a href="LocalService.html">LocalService</a> that runs in the same
+  process as the activity, to demonstrate using the
+  {@link android.content.Context#bindService Context.bindService} and
+  {@link android.content.Context#unbindService Context.unindService}
+  methods with a service.  This also shows how you can simplify working
+  with a service when you know it will only run in your own process.</dd>
+
+  <dt><a href="RemoteServiceController.html">Remote Service Controller</a></dt>
+  <dd>Demonstrates starting a service in a separate process, by assigning
+  <code>android:process=&quot;:remote&quot;</code> to the service in the
+  AndroidManifest.xml file. </dd>
+
+  <dt><a href="RemoteServiceBinding.html">Remote Service Binding</a></dt>
+  <dd>Demonstrates binding to a remote service, similar to the Local Service
+  Binding sample, but illustrating the additional work (defining aidl
+  interfaces) needed to interact with a service in another process.  Also
+  shows how a service can publish multiple interfaces and implement
+  callbacks to its clients.</dd>
+
+  <dt><a href="ServiceStartArgumentsController.html">Service Start Arguments Controller</a></dt>
+  <dd>Demonstrates how you can use a Service as a job queue, where you 
+  submit jobs to it with {@link android.content.Context#startService
+  Context.startService} instead of binding to the service.  Such a service
+  automatically stops itself once all jobs have been processed.  This can be
+  a very convenient way to interact with a service when you do not need
+  a result back from it.
+  <dl>
+  <dt>Code:
+  <dd> <a href="ServiceStartArgumentsController.html">ServiceStartArgumentsController.java</a>
+  <dd> <a href="ServiceStartArguments.html">ServiceStartArguments.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/service_start_arguments_controller.html">
+  service_start_arguments_controller.xml</a>
+  </dl>
+  </dd>
+</dl>
+
+<h3>Alarm</h3>
+<dl>
+  <dt><a href="AlarmController.html">Alarm Controller</a></dt>
+  <dd>Demonstrates two ways you can schedule alarms: a one-shot alarm that
+  will happen once at a given time, and a repeating alarm that will happen
+  first at a given time and then continually trigger at regular intervals
+  after that.
+  <dl>
+  <dt>Code:
+  <dd> <a href="AlarmController.html">AlarmController.java</a>
+  <dd> <a href="OneShotAlarm.html">OneShotAlarm.java</a>
+  <dd> <a href="RepeatingAlarm.html">RepeatingAlarm.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/alarm_controller.html">
+  alarm_controller.xml</a>
+  </dl>
+  </dd>
+
+  <dt><a href="AlarmService.html">Alarm Service</a></dt>
+  <dd>Demonstrates how you can schedule an alarm that causes a service to
+    be started.  This is useful when you want to schedule alarms that initiate
+    long-running operations, such as retrieving recent e-mails.
+  <dl>
+  <dt>Code:
+  <dd> <a href="AlarmService.html">AlarmService.java</a>
+  <dd> <a href="AlarmService_Service.html">AlarmService_Service.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/alarm_service.html">
+  alarm_service.xml</a>
+  </dl>
+  </dd>
+</dl>
+
+<h3>Notification</h3>
+<dl>
+  <dt><a href="NotifyWithText.html">NotifyWithText</a></dt>
+  <dd>Demonstrates popup notifications of varying length.</dd>
+
+  <dt><a href="IncomingMessage.html">IncomingMessage</a></dt>
+  <dd> Demonstrates sending persistent and transient notifications, with a View object in the notification. It also demonstrated inflating a View object from an XML layout resource. </dd>
+</dl>
+
+<h3>Search</h3>
+<dl>
+  <dt><a href="SearchInvoke.html">SearchInvoke</a></dt>
+  <dd>Demonstrates various ways in which activities can launch the Search UI.</dd>
+  
+  <dt><a href="SearchQueryResults.html">SearchQueryResults</a></dt>
+  <dd>Demonstrates an activity that receives Search intents and handles them.</dd>
+  
+  <dt><a href="SearchSuggestionSampleProvider.html">SearchSuggestionSampleProvider</a></dt>
+  <dd>Demonstrates how to configure and use the built-in "recent queries" suggestion provider.</dd>  
+</dl>
+
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/_package.html b/samples/ApiDemos/src/com/example/android/apis/app/_package.html
new file mode 100644
index 0000000..7f99501
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/_package.html
@@ -0,0 +1,48 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="assets/style.css" />
+<script type="text/javascript" src="http://www.corp.google.com/style/prettify.js"></script>
+<script src="http://www.corp.google.com/eng/techpubs/include/navbar.js" type="text/javascript"></script>
+
+
+
+</head>
+
+<body>
+
+<p>
+Examples of how to use the android.app APIs.
+
+<ol>
+	<li> Activities
+        - These examples show various ways you can use activities to implement an
+application's user interface.
+            <ol>
+			<li> {@link com.android.samples.app.HelloWorld Hello World}
+			<li> {@link com.android.samples.app.SaveRestoreState Save &amp; Restore State}
+			<li>{@link com.android.samples.app.PersistentState Persistent State}
+			<li>{@link com.android.samples.app.ReceiveResult Receive Result}
+			<li>{@link com.android.samples.app.Forwarding Forwarding}
+			</ol>
+	<li> Services
+        - These examples show how you can implement application services, which
+give you a way to run code in the background outside of the normal UI flow.
+            <ol>
+			<li>{@link com.android.samples.app.LocalServiceController Local Service
+			    Controller}
+			<li>{@link com.android.samples.app.LocalServiceBinding Local Service Binding}
+			<li>{@link com.android.samples.app.RemoteServiceController Remote Service
+			    Controller}
+			<li>{@link com.android.samples.app.RemoteServiceBinding Remote Service
+			    Binding}
+			</ol>
+	<li> Alarms
+        - These examples show how you can use alarms to schedule background
+events.
+            <ol>
+			<li>{@link com.android.samples.app.AlarmController Alarm Controller}
+			<li>{@link com.android.samples.app.AlarmService Alarm Service}
+			</ol>
+</ol>
+</body>
+</html>
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ReadAsset.java b/samples/ApiDemos/src/com/example/android/apis/content/ReadAsset.java
new file mode 100644
index 0000000..47503c4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ReadAsset.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.content;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * Demonstration of styled text resources.
+ */
+public class ReadAsset extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/styled_text.xml for this
+        // view layout definition.
+        setContentView(R.layout.read_asset);
+
+        // Programmatically load text from an asset and place it into the
+        // text view.  Note that the text we are loading is ASCII, so we
+        // need to convert it to UTF-16.
+        try {
+            InputStream is = getAssets().open("read_asset.txt");
+            
+            // We guarantee that the available method returns the total
+            // size of the asset...  of course, this does mean that a single
+            // asset can't be more than 2 gigs.
+            int size = is.available();
+            
+            // Read the entire asset into a local byte buffer.
+            byte[] buffer = new byte[size];
+            is.read(buffer);
+            is.close();
+            
+            // Convert the buffer into a string.
+            String text = new String(buffer);
+            
+            // Finally stick the string into the text view.
+            TextView tv = (TextView)findViewById(R.id.text);
+            tv.setText(text);
+        } catch (IOException e) {
+            // Should never happen!
+            throw new RuntimeException(e);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java b/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java
new file mode 100755
index 0000000..f38be0f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ResourcesSample.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.content;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.widget.TextView;
+
+
+/**
+ * Demonstration of loading resources.
+ * 
+ * <p>
+ * Each context has a resources object that you can access.  Additionally,
+ * the Context class (an Activity is a Context) has a getString convenience
+ * method getString() that looks up a string resource.
+ *
+ * @see StyledText for more depth about using styled text, both with getString()
+ *                 and in the layout xml files.
+ */
+public class ResourcesSample extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        // See res/any/layout/resources.xml for this view layout definition.
+        setContentView(R.layout.resources);
+
+        TextView tv;
+        CharSequence cs;
+        String str;
+
+        // ====== Using the Context.getString() convenience method ===========
+
+        // Using the getString() conevenience method, retrieve a string
+        // resource that hapepns to have style information.  Note the use of
+        // CharSequence instead of String so we don't lose the style info.
+        cs = getText(R.string.styled_text);
+        tv = (TextView)findViewById(R.id.styled_text);
+        tv.setText(cs);
+
+        // Use the same resource, but convert it to a string, which causes it
+        // to lose the style information.
+        str = getString(R.string.styled_text);
+        tv = (TextView)findViewById(R.id.plain_text);
+        tv.setText(str);
+
+        // ====== Using the Resources object =================================
+        
+        // You might need to do this if your code is not in an activity.
+        // For example View has a protected mContext field you can use.
+        // In this case it's just 'this' since Activity is a context.
+        Context context = this;
+
+        // Get the Resources object from our context
+        Resources res = context.getResources();
+
+        // Get the string resource, like above.
+        cs = res.getText(R.string.styled_text);
+        tv = (TextView)findViewById(R.id.res1);
+        tv.setText(cs);
+
+        // Note that the Resources class has methods like getColor(),
+        // getDimen(), getDrawable() because themes are stored in resources.
+        // You can use them, but you might want to take a look at the view
+        // examples to see how to make custom widgets.
+
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/StyledText.java b/samples/ApiDemos/src/com/example/android/apis/content/StyledText.java
new file mode 100644
index 0000000..b158929
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/StyledText.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.content;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+
+/**
+ * Demonstration of styled text resources.
+ */
+public class StyledText extends Activity
+{
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/styled_text.xml for this
+        // view layout definition.
+        setContentView(R.layout.styled_text);
+
+        // Programmatically retrieve a string resource with style
+        // information and apply it to the second text view.  Note the
+        // use of CharSequence instead of String so we don't lose
+        // the style info.
+        CharSequence str = getText(R.string.styled_text);
+        TextView tv = (TextView)findViewById(R.id.text);
+        tv.setText(str);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/_index.html b/samples/ApiDemos/src/com/example/android/apis/content/_index.html
new file mode 100644
index 0000000..1aa52b3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/_index.html
@@ -0,0 +1,8 @@
+<h3>Resources</h3>
+<dl>
+  <dt><a href="StyledText.html">Styled Text</a></dt>
+  <dd>Demonstrates loading styled text (bold, italic) defined in a resource file. </dd>
+
+  <dt><a href="ResourcesSample.html">Resources</a></dt>
+  <dd>Demonstrates loading styled strings from a resource file, and extracting the raw text. </dd>
+</dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleBroadcastReceiver.java b/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleBroadcastReceiver.java
new file mode 100644
index 0000000..eec10b2
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleBroadcastReceiver.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 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.gadget;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.gadget.GadgetManager;
+import android.gadget.GadgetProvider;
+import android.os.SystemClock;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import java.util.ArrayList;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * A BroadcastReceiver that listens for updates for the ExampleGadgetProvider.  This
+ * BroadcastReceiver starts off disabled, and we only enable it when there is a gadget
+ * instance created, in order to only receive notifications when we need them.
+ */
+public class ExampleBroadcastReceiver extends BroadcastReceiver {
+
+    public void onReceive(Context context, Intent intent) {
+        Log.d("ExmampleBroadcastReceiver", "intent=" + intent);
+
+        // For our example, we'll also update all of the gadgets when the timezone
+        // changes, or the user or network sets the time.
+        String action = intent.getAction();
+        if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)
+                || action.equals(Intent.ACTION_TIME_CHANGED)) {
+            GadgetManager gm = GadgetManager.getInstance(context);
+            ArrayList<Integer> gadgetIds = new ArrayList();
+            ArrayList<String> texts = new ArrayList();
+
+            ExampleGadgetConfigure.loadAllTitlePrefs(context, gadgetIds, texts);
+
+            final int N = gadgetIds.size();
+            for (int i=0; i<N; i++) {
+                ExampleGadgetProvider.updateGadget(context, gm, gadgetIds.get(i), texts.get(i));
+            }
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleGadgetConfigure.java b/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleGadgetConfigure.java
new file mode 100644
index 0000000..03e7bb4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleGadgetConfigure.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 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.gadget;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.gadget.GadgetManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+
+import java.util.ArrayList;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * The configuration screen for the ExampleGadgetProvider gadget sample.
+ */
+public class ExampleGadgetConfigure extends Activity {
+    static final String TAG = "ExampleGadgetConfigure";
+
+    private static final String PREFS_NAME
+            = "com.example.android.apis.gadget.ExampleGadgetProvider";
+    private static final String PREF_PREFIX_KEY = "prefix_";
+
+    int mGadgetId = GadgetManager.INVALID_GADGET_ID;
+    EditText mGadgetPrefix;
+
+    public ExampleGadgetConfigure() {
+        super();
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Set the result to CANCELED.  This will cause the gadget host to cancel
+        // out of the gadget placement if they press the back button.
+        setResult(RESULT_CANCELED);
+
+        // Set the view layout resource to use.
+        setContentView(R.layout.gadget_configure);
+
+        // Find the EditText
+        mGadgetPrefix = (EditText)findViewById(R.id.gadget_prefix);
+
+        // Bind the action for the save button.
+        findViewById(R.id.save_button).setOnClickListener(mOnClickListener);
+
+        // Find the gadget id from the intent. 
+        Intent intent = getIntent();
+        Bundle extras = intent.getExtras();
+        if (extras != null) {
+            mGadgetId = extras.getInt(
+                    GadgetManager.EXTRA_GADGET_ID, GadgetManager.INVALID_GADGET_ID);
+        }
+
+        // If they gave us an intent without the gadget id, just bail.
+        if (mGadgetId == GadgetManager.INVALID_GADGET_ID) {
+            finish();
+        }
+
+        mGadgetPrefix.setText(loadTitlePref(ExampleGadgetConfigure.this, mGadgetId));
+    }
+
+    View.OnClickListener mOnClickListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            // When the button is clicked, save the string in our prefs and return that they
+            // clicked OK.
+            saveTitlePref(ExampleGadgetConfigure.this, mGadgetId,
+                    mGadgetPrefix.getText().toString());
+
+            setResult(RESULT_OK);
+            finish();
+        }
+    };
+
+    // Write the prefix to the SharedPreferences object for this gadget
+    static void saveTitlePref(Context context, int gadgetId, String text) {
+        SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
+        prefs.putString(PREF_PREFIX_KEY + gadgetId, text);
+        prefs.commit();
+    }
+
+    // Read the prefix from the SharedPreferences object for this gadget.
+    // If there is no preference saved, get the default from a resource
+    static String loadTitlePref(Context context, int gadgetId) {
+        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
+        String prefix = prefs.getString(PREF_PREFIX_KEY, null);
+        if (prefix != null) {
+            return prefix;
+        } else {
+            return context.getString(R.string.gadget_prefix_default);
+        }
+    }
+
+    static void deleteTitlePref(Context context, int gadgetId) {
+    }
+
+    static void loadAllTitlePrefs(Context context, ArrayList<Integer> gadgetIds,
+            ArrayList<String> texts) {
+    }
+}
+
+
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleGadgetProvider.java b/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleGadgetProvider.java
new file mode 100644
index 0000000..eb1dab3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/gadget/ExampleGadgetProvider.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008 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.gadget;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.gadget.GadgetManager;
+import android.gadget.GadgetProvider;
+import android.os.SystemClock;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import java.util.ArrayList;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * A gadget provider.  We have a string that we pull from a preference in order to show
+ * the configuration settings and the current time when the gadget was updated.  We also
+ * register a BroadcastReceiver for time-changed and timezone-changed broadcasts, and
+ * update then too.
+ *
+ * <p>See also the following files:
+ * <ul>
+ *   <li>ExampleGadgetConfigure.java</li>
+ *   <li>ExampleBroadcastReceiver.java</li>
+ *   <li>res/layout/gadget_configure.xml</li>
+ *   <li>res/layout/gadget_provider.xml</li>
+ *   <li>res/xml/gadget_provider.xml</li>
+ * </ul>
+ */
+public class ExampleGadgetProvider extends GadgetProvider {
+    // log tag
+    private static final String TAG = "ExampleGadgetProvider";
+
+    public void onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds) {
+        Log.d(TAG, "onUpdate");
+        // For each gadget that needs an update, get the text that we should display:
+        //   - Create a RemoteViews object for it
+        //   - Set the text in the RemoteViews object
+        //   - Tell the GadgetManager to show that views object for the gadget.
+        final int N = gadgetIds.length;
+        for (int i=0; i<N; i++) {
+            int gadgetId = gadgetIds[i];
+            String titlePrefix = ExampleGadgetConfigure.loadTitlePref(context, gadgetId);
+            updateGadget(context, gadgetManager, gadgetId, titlePrefix);
+        }
+    }
+    
+    public void onDeleted(Context context, int[] gadgetIds) {
+        Log.d(TAG, "onDeleted");
+        // When the user deletes the gadget, delete the preference associated with it.
+        final int N = gadgetIds.length;
+        for (int i=0; i<N; i++) {
+            ExampleGadgetConfigure.deleteTitlePref(context, gadgetIds[i]);
+        }
+    }
+
+    public void onEnabled(Context context) {
+        Log.d(TAG, "onEnabled");
+        // When the first gadget is created, register for the TIMEZONE_CHANGED and TIME_CHANGED
+        // broadcasts.  We don't want to be listening for these if nobody has our gadget active.
+        // This setting is sticky across reboots, but that doesn't matter, because this will
+        // be called after boot if there is a gadget instance for this provider.
+        PackageManager pm = context.getPackageManager();
+        pm.setComponentEnabledSetting(
+                new ComponentName("com.example.android.apis", ".gadget.ExampleBroadcastReceiver"),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                PackageManager.DONT_KILL_APP);
+    }
+
+    public void onDisabled(Context context) {
+        // When the first gadget is created, stop listening for the TIMEZONE_CHANGED and
+        // TIME_CHANGED broadcasts.
+        Log.d(TAG, "onDisabled");
+        Class clazz = ExampleBroadcastReceiver.class;
+        PackageManager pm = context.getPackageManager();
+        pm.setComponentEnabledSetting(
+                new ComponentName("com.example.android.apis", ".gadget.ExampleBroadcastReceiver"),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                PackageManager.DONT_KILL_APP);
+    }
+
+    static void updateGadget(Context context, GadgetManager gadgetManager,
+            int gadgetId, String titlePrefix) {
+        Log.d(TAG, "updateGadget gadgetId=" + gadgetId + " titlePrefix=" + titlePrefix);
+        // Getting the string this way allows the string to be localized.  The format
+        // string is filled in using java.util.Formatter-style format strings.
+        CharSequence text = context.getString(R.string.gadget_text_format,
+                ExampleGadgetConfigure.loadTitlePref(context, gadgetId),
+                "0x" + Long.toHexString(SystemClock.elapsedRealtime()));
+
+        // Construct the RemoteViews object.  It takes the package name (in our case, it's our
+        // package, but it needs this because on the other side it's the gadget host inflating
+        // the layout from our package).
+        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.gadget_provider);
+        views.setTextViewText(R.id.gadget_text, text);
+
+        // Tell the gadget manager
+        gadgetManager.updateGadget(gadgetId, views);
+    }
+}
+
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
new file mode 100644
index 0000000..8fff231
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+
+public class AlphaBitmap extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Bitmap mBitmap;
+        private Bitmap mBitmap2;
+        private Bitmap mBitmap3;
+        private Shader mShader;
+        
+        private static void drawIntoBitmap(Bitmap bm) {
+            float x = bm.getWidth();
+            float y = bm.getHeight();
+            Canvas c = new Canvas(bm);
+            Paint p = new Paint();
+            p.setAntiAlias(true);
+            
+            p.setAlpha(0x80);
+            c.drawCircle(x/2, y/2, x/2, p);
+            
+            p.setAlpha(0x30);
+            p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
+            p.setTextSize(60);
+            p.setTextAlign(Paint.Align.CENTER);
+            Paint.FontMetrics fm = p.getFontMetrics();
+            c.drawText("Alpha", x/2, (y-fm.ascent)/2, p);
+        }
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            InputStream is = context.getResources().openRawResource(R.drawable.app_sample_code);
+            mBitmap = BitmapFactory.decodeStream(is);
+            mBitmap2 = mBitmap.extractAlpha();
+            mBitmap3 = Bitmap.createBitmap(200, 200, Bitmap.Config.ALPHA_8);
+            drawIntoBitmap(mBitmap3);
+            
+            mShader = new LinearGradient(0, 0, 100, 70, new int[] {
+                                         Color.RED, Color.GREEN, Color.BLUE },
+                                         null, Shader.TileMode.MIRROR);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+
+            Paint p = new Paint();
+            float y = 10;
+            
+            p.setColor(Color.RED);
+            canvas.drawBitmap(mBitmap, 10, y, p);
+            y += mBitmap.getHeight() + 10;
+            canvas.drawBitmap(mBitmap2, 10, y, p);
+            y += mBitmap2.getHeight() + 10;
+            p.setShader(mShader);
+            canvas.drawBitmap(mBitmap3, 10, y, p);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
new file mode 100644
index 0000000..279b588
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Transformation;
+
+public class AnimateDrawable extends ProxyDrawable {
+    
+    private Animation mAnimation;
+    private Transformation mTransformation = new Transformation();
+
+    public AnimateDrawable(Drawable target) {
+        super(target);
+    }
+    
+    public AnimateDrawable(Drawable target, Animation animation) {
+        super(target);
+        mAnimation = animation;
+    }
+    
+    public Animation getAnimation() {
+        return mAnimation;
+    }
+    
+    public void setAnimation(Animation anim) {
+        mAnimation = anim;
+    }
+
+    public boolean hasStarted() {
+        return mAnimation != null && mAnimation.hasStarted();
+    }
+    
+    public boolean hasEnded() {
+        return mAnimation == null || mAnimation.hasEnded();
+    }
+    
+    @Override
+    public void draw(Canvas canvas) {
+        Drawable dr = getProxy();
+        if (dr != null) {
+            int sc = canvas.save();
+            Animation anim = mAnimation;
+            if (anim != null) {
+                anim.getTransformation(
+                                    AnimationUtils.currentAnimationTimeMillis(),
+                                    mTransformation);
+                canvas.concat(mTransformation.getMatrix());
+            }
+            dr.draw(canvas);
+            canvas.restoreToCount(sc);
+        }
+    }
+}
+    
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
new file mode 100644
index 0000000..7c9473d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.*;
+import android.view.animation.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+public class AnimateDrawables extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private AnimateDrawable mDrawable;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+
+            Drawable dr = context.getResources().getDrawable(R.drawable.beach);
+            dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
+            
+            Animation an = new TranslateAnimation(0, 100, 0, 200);
+            an.setDuration(2000);
+            an.setRepeatCount(-1);
+            an.initialize(10, 10, 10, 10);
+            
+            mDrawable = new AnimateDrawable(dr, an);
+            an.startNow();
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+
+            mDrawable.draw(canvas);
+            invalidate();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
new file mode 100644
index 0000000..ff8b38b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+//import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class Arcs extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint[] mPaints;
+        private Paint mFramePaint;
+        private boolean[] mUseCenters;
+        private RectF[] mOvals;
+        private RectF mBigOval;
+        private float mStart;
+        private float mSweep;
+        private int mBigIndex;
+        
+        private static final float SWEEP_INC = 2;
+        private static final float START_INC = 15;
+        
+        public SampleView(Context context) {
+            super(context);
+            
+            mPaints = new Paint[4];
+            mUseCenters = new boolean[4];
+            mOvals = new RectF[4];
+    
+            mPaints[0] = new Paint();
+            mPaints[0].setAntiAlias(true);
+            mPaints[0].setStyle(Paint.Style.FILL);
+            mPaints[0].setColor(0x88FF0000);
+            mUseCenters[0] = false;
+            
+            mPaints[1] = new Paint(mPaints[0]);
+            mPaints[1].setColor(0x8800FF00);
+            mUseCenters[1] = true;
+            
+            mPaints[2] = new Paint(mPaints[0]);
+            mPaints[2].setStyle(Paint.Style.STROKE);
+            mPaints[2].setStrokeWidth(4);
+            mPaints[2].setColor(0x880000FF);
+            mUseCenters[2] = false;
+
+            mPaints[3] = new Paint(mPaints[2]);
+            mPaints[3].setColor(0x88888888);
+            mUseCenters[3] = true;
+            
+            mBigOval = new RectF(40, 10, 280, 250);
+            
+            mOvals[0] = new RectF( 10, 270,  70, 330);
+            mOvals[1] = new RectF( 90, 270, 150, 330);
+            mOvals[2] = new RectF(170, 270, 230, 330);
+            mOvals[3] = new RectF(250, 270, 310, 330);
+            
+            mFramePaint = new Paint();
+            mFramePaint.setAntiAlias(true);
+            mFramePaint.setStyle(Paint.Style.STROKE);
+            mFramePaint.setStrokeWidth(0);
+        }
+        
+        private void drawArcs(Canvas canvas, RectF oval, boolean useCenter,
+                              Paint paint) {
+            canvas.drawRect(oval, mFramePaint);
+            canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+            
+            drawArcs(canvas, mBigOval, mUseCenters[mBigIndex],
+                     mPaints[mBigIndex]);
+            
+            for (int i = 0; i < 4; i++) {
+                drawArcs(canvas, mOvals[i], mUseCenters[i], mPaints[i]);
+            }
+            
+            mSweep += SWEEP_INC;
+            if (mSweep > 360) {
+                mSweep -= 360;
+                mStart += START_INC;
+                if (mStart >= 360) {
+                    mStart -= 360;
+                }
+                mBigIndex = (mBigIndex + 1) % mOvals.length;
+            }
+            invalidate();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
new file mode 100644
index 0000000..88f0c1d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+
+public class BitmapDecode extends GraphicsActivity {
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Bitmap mBitmap;
+        private Bitmap mBitmap2;
+        private Bitmap mBitmap3;
+        private Bitmap mBitmap4;
+        private Drawable mDrawable;
+        
+        private Movie mMovie;
+        private long mMovieStart;
+        
+        private static byte[] streamToBytes(InputStream is) {
+            ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
+            byte[] buffer = new byte[1024];
+            int len;
+            try {
+                while ((len = is.read(buffer)) >= 0) {
+                    os.write(buffer, 0, len);
+                }
+            } catch (java.io.IOException e) {
+            }
+            return os.toByteArray();
+        }
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            java.io.InputStream is;
+            is = context.getResources().openRawResource(R.drawable.beach);
+            
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            Bitmap bm;
+            
+            opts.inJustDecodeBounds = true;
+            bm = BitmapFactory.decodeStream(is, null, opts);
+            
+            // now opts.outWidth and opts.outHeight are the dimension of the
+            // bitmap, even though bm is null
+            
+            opts.inJustDecodeBounds = false;    // this will request the bm
+            opts.inSampleSize = 4;             // scaled down by 4
+            bm = BitmapFactory.decodeStream(is, null, opts);
+            
+            mBitmap = bm;
+            
+            // decode an image with transparency
+            is = context.getResources().openRawResource(R.drawable.frog);
+            mBitmap2 = BitmapFactory.decodeStream(is);
+            
+            // create a deep copy of it using getPixels() into different configs
+            int w = mBitmap2.getWidth();
+            int h = mBitmap2.getHeight();
+            int[] pixels = new int[w*h];
+            mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
+            mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
+                                           Bitmap.Config.ARGB_8888);
+            mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
+                                           Bitmap.Config.ARGB_4444);
+            
+            mDrawable = context.getResources().getDrawable(R.drawable.button);
+            mDrawable.setBounds(150, 20, 300, 100);
+            
+            is = context.getResources().openRawResource(R.drawable.animated_gif);
+            if (true) {
+                mMovie = Movie.decodeStream(is);
+            } else {
+                byte[] array = streamToBytes(is);
+                mMovie = Movie.decodeByteArray(array, 0, array.length);
+            }
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(0xFFCCCCCC);            
+            
+            Paint p = new Paint();
+            p.setAntiAlias(true);
+            
+            canvas.drawBitmap(mBitmap, 10, 10, null);
+            canvas.drawBitmap(mBitmap2, 10, 170, null);
+            canvas.drawBitmap(mBitmap3, 110, 170, null);
+            canvas.drawBitmap(mBitmap4, 210, 170, null);
+            
+            mDrawable.draw(canvas);
+            
+            long now = android.os.SystemClock.uptimeMillis();
+            if (mMovieStart == 0) {   // first time
+                mMovieStart = now;
+            }
+            if (mMovie != null) {
+                int dur = mMovie.duration();
+                if (dur == 0) {
+                    dur = 1000;
+                }
+                int relTime = (int)((now - mMovieStart) % dur);
+                mMovie.setTime(relTime);
+                mMovie.draw(canvas, getWidth() - mMovie.width(),
+                            getHeight() - mMovie.height());
+                invalidate();
+            }
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
new file mode 100644
index 0000000..4d48a1e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import com.example.android.apis.R;
+
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.*;
+import android.util.FloatMath;
+
+public class BitmapMesh extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private static final int WIDTH = 20;
+        private static final int HEIGHT = 20;
+        private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
+        
+        private final Bitmap mBitmap;
+        private final float[] mVerts = new float[COUNT*2];
+        private final float[] mOrig = new float[COUNT*2];
+        
+        private final Matrix mMatrix = new Matrix();
+        private final Matrix mInverse = new Matrix();
+
+        private static void setXY(float[] array, int index, float x, float y) {
+            array[index*2 + 0] = x;
+            array[index*2 + 1] = y;
+        }
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+
+            mBitmap = BitmapFactory.decodeResource(getResources(),
+                                                     R.drawable.beach);
+            
+            float w = mBitmap.getWidth();
+            float h = mBitmap.getHeight();
+            // construct our mesh
+            int index = 0;
+            for (int y = 0; y <= HEIGHT; y++) {
+                float fy = h * y / HEIGHT;
+                for (int x = 0; x <= WIDTH; x++) {
+                    float fx = w * x / WIDTH;                    
+                    setXY(mVerts, index, fx, fy);
+                    setXY(mOrig, index, fx, fy);
+                    index += 1;
+                }
+            }
+            
+            mMatrix.setTranslate(10, 10);
+            mMatrix.invert(mInverse);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(0xFFCCCCCC);
+
+            canvas.concat(mMatrix);
+            canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0,
+                                  null, 0, null);
+        }
+        
+        private void warp(float cx, float cy) {
+            final float K = 10000;
+            float[] src = mOrig;
+            float[] dst = mVerts;
+            for (int i = 0; i < COUNT*2; i += 2) {
+                float x = src[i+0];
+                float y = src[i+1];
+                float dx = cx - x;
+                float dy = cy - y;
+                float dd = dx*dx + dy*dy;
+                float d = FloatMath.sqrt(dd);
+                float pull = K / (dd + 0.000001f);
+                
+                pull /= (d + 0.000001f);
+             //   android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull);
+
+                if (pull >= 1) {
+                    dst[i+0] = cx;
+                    dst[i+1] = cy;
+                } else {
+                    dst[i+0] = x + dx * pull;
+                    dst[i+1] = y + dy * pull;
+                }
+            }
+        }
+
+        private int mLastWarpX = -9999; // don't match a touch coordinate
+        private int mLastWarpY;
+
+        @Override public boolean onTouchEvent(MotionEvent event) {
+            float[] pt = { event.getX(), event.getY() };
+            mInverse.mapPoints(pt);
+            
+            int x = (int)pt[0];
+            int y = (int)pt[1];
+            if (mLastWarpX != x || mLastWarpY != y) {
+                mLastWarpX = x;
+                mLastWarpY = y;
+                warp(pt[0], pt[1]);
+                invalidate();
+            }
+            return true;
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
new file mode 100644
index 0000000..88717bc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+
+public class BitmapPixels extends GraphicsActivity {
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Bitmap mBitmap1;
+        private Bitmap mBitmap2;
+        private Bitmap mBitmap3;
+        private Bitmap mBitmap4;
+
+        // access the red component from a premultiplied color
+        private static int getR32(int c) { return (c >>  0) & 0xFF; }
+        // access the red component from a premultiplied color
+        private static int getG32(int c) { return (c >>  8) & 0xFF; }
+        // access the red component from a premultiplied color
+        private static int getB32(int c) { return (c >> 16) & 0xFF; }
+        // access the red component from a premultiplied color
+        private static int getA32(int c) { return (c >> 24) & 0xFF; }
+
+        /**
+         * This takes components that are already in premultiplied form, and
+         * packs them into an int in the correct device order.
+         */
+        private static int pack8888(int r, int g, int b, int a) {
+            return (r << 0) | ( g << 8) | (b << 16) | (a << 24);
+        }
+
+        private static short pack565(int r, int g, int b) {
+            return (short)((r << 11) | ( g << 5) | (b << 0));
+        }
+
+        private static short pack4444(int r, int g, int b, int a) {
+            return (short)((a << 0) | ( b << 4) | (g << 8) | (r << 12));
+        }
+        
+        private static int mul255(int c, int a) {
+            int prod = c * a + 128;
+            return (prod + (prod >> 8)) >> 8;
+        }
+
+        /**
+         * Turn a color int into a premultiplied device color
+         */
+        private static int premultiplyColor(int c) {
+            int r = Color.red(c);
+            int g = Color.green(c);
+            int b = Color.blue(c);
+            int a = Color.alpha(c);
+            // now apply the alpha to r, g, b
+            r = mul255(r, a);
+            g = mul255(g, a);
+            b = mul255(b, a);
+            // now pack it in the correct order
+            return pack8888(r, g, b, a);
+        }
+        
+        private static void makeRamp(int from, int to, int n,
+                                     int[] ramp8888, short[] ramp565,
+                                     short[] ramp4444) {
+            int r = getR32(from) << 23;
+            int g = getG32(from) << 23;
+            int b = getB32(from) << 23;
+            int a = getA32(from) << 23;
+            // now compute our step amounts per componenet (biased by 23 bits)
+            int dr = ((getR32(to) << 23) - r) / (n - 1);
+            int dg = ((getG32(to) << 23) - g) / (n - 1);
+            int db = ((getB32(to) << 23) - b) / (n - 1);
+            int da = ((getA32(to) << 23) - a) / (n - 1);
+
+            for (int i = 0; i < n; i++) {
+                ramp8888[i] = pack8888(r >> 23, g >> 23, b >> 23, a >> 23);
+                ramp565[i] = pack565(r >> (23+3), g >> (23+2), b >> (23+3));
+                ramp4444[i] = pack4444(r >> (23+4), g >> (23+4), b >> (23+4),
+                                       a >> (23+4));
+                r += dr;
+                g += dg;
+                b += db;
+                a += da;
+            }
+        }
+        
+        private static IntBuffer makeBuffer(int[] src, int n) {
+            IntBuffer dst = IntBuffer.allocate(n*n);
+            for (int i = 0; i < n; i++) {
+                dst.put(src);
+            }
+            dst.rewind();
+            return dst;
+        }
+        
+        private static ShortBuffer makeBuffer(short[] src, int n) {
+            ShortBuffer dst = ShortBuffer.allocate(n*n);
+            for (int i = 0; i < n; i++) {
+                dst.put(src);
+            }
+            dst.rewind();
+            return dst;
+        }
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            final int N = 100;
+            int[] data8888 = new int[N];
+            short[] data565 = new short[N];
+            short[] data4444 = new short[N];
+            
+            makeRamp(premultiplyColor(Color.RED), premultiplyColor(Color.GREEN),
+                     N, data8888, data565, data4444);
+            
+            mBitmap1 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_8888);
+            mBitmap2 = Bitmap.createBitmap(N, N, Bitmap.Config.RGB_565);
+            mBitmap3 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_4444);
+            
+            mBitmap1.copyPixelsFromBuffer(makeBuffer(data8888, N));
+            mBitmap2.copyPixelsFromBuffer(makeBuffer(data565, N));
+            mBitmap3.copyPixelsFromBuffer(makeBuffer(data4444, N));
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(0xFFCCCCCC);            
+            
+            int y = 10;
+            canvas.drawBitmap(mBitmap1, 10, y, null);
+            y += mBitmap1.getHeight() + 10;
+            canvas.drawBitmap(mBitmap2, 10, y, null);
+            y += mBitmap2.getHeight() + 10;
+            canvas.drawBitmap(mBitmap3, 10, y, null);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java
new file mode 100644
index 0000000..ceff150
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.Window;
+import java.io.IOException;
+
+// ----------------------------------------------------------------------
+
+public class CameraPreview extends Activity {    
+    private Preview mPreview;
+    
+    @Override
+	protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Hide the window title.
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+    
+        // Create our Preview view and set it as the content of our activity.
+        mPreview = new Preview(this);
+        setContentView(mPreview);
+    }
+
+}
+
+// ----------------------------------------------------------------------
+
+class Preview extends SurfaceView implements SurfaceHolder.Callback {
+    SurfaceHolder mHolder;
+    Camera mCamera;
+    
+    Preview(Context context) {
+        super(context);
+        
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed.
+        mHolder = getHolder();
+        mHolder.addCallback(this);
+        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+    }
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        // The Surface has been created, acquire the camera and tell it where
+        // to draw.
+        mCamera = Camera.open();
+        try {
+           mCamera.setPreviewDisplay(holder);
+        } catch (IOException exception) {
+            mCamera.release();
+            mCamera = null;
+            // TODO: add more exception handling logic here
+        }
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // Surface will be destroyed when we return, so stop the preview.
+        // Because the CameraDevice object is not a shared resource, it's very
+        // important to release it when the activity is paused.
+        mCamera.stopPreview();
+        mCamera = null;
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        // Now that the size is known, set up the camera parameters and begin
+        // the preview.
+        Camera.Parameters parameters = mCamera.getParameters();
+        parameters.setPreviewSize(w, h);
+        mCamera.setParameters(parameters);
+        mCamera.startPreview();
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
new file mode 100644
index 0000000..cf83597
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class Clipping extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint mPaint;
+        private Path mPath;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setStrokeWidth(6);
+            mPaint.setTextSize(16);
+            mPaint.setTextAlign(Paint.Align.RIGHT);
+            
+            mPath = new Path();
+        }
+        
+        private void drawScene(Canvas canvas) {
+            canvas.clipRect(0, 0, 100, 100);
+            
+            canvas.drawColor(Color.WHITE);
+            
+            mPaint.setColor(Color.RED);
+            canvas.drawLine(0, 0, 100, 100, mPaint);
+            
+            mPaint.setColor(Color.GREEN);
+            canvas.drawCircle(30, 70, 30, mPaint);
+            
+            mPaint.setColor(Color.BLUE);
+            canvas.drawText("Clipping", 100, 30, mPaint);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.GRAY);            
+
+            canvas.save();
+            canvas.translate(10, 10);
+            drawScene(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(160, 10);
+            canvas.clipRect(10, 10, 90, 90);
+            canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
+            drawScene(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(10, 160);
+            mPath.reset();
+            canvas.clipPath(mPath); // makes the clip empty
+            mPath.addCircle(50, 50, 50, Path.Direction.CCW);
+            canvas.clipPath(mPath, Region.Op.REPLACE);
+            drawScene(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(160, 160);
+            canvas.clipRect(0, 0, 60, 60);
+            canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);
+            drawScene(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(10, 310);
+            canvas.clipRect(0, 0, 60, 60);
+            canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);
+            drawScene(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(160, 310);
+            canvas.clipRect(0, 0, 60, 60);
+            canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE);
+            drawScene(canvas);
+            canvas.restore();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
new file mode 100644
index 0000000..19a0f7f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+public class ColorMatrixSample extends GraphicsActivity {
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private ColorMatrix mCM = new ColorMatrix();
+        private Bitmap mBitmap;
+        private float mSaturation;
+        private float mAngle;
+        
+        public SampleView(Context context) {
+            super(context);
+            
+            mBitmap = BitmapFactory.decodeResource(context.getResources(),
+                                                   R.drawable.balloons);
+        }
+        
+        private static void setTranslate(ColorMatrix cm, float dr, float dg,
+                                         float db, float da) {
+            cm.set(new float[] {
+                   2, 0, 0, 0, dr,
+                   0, 2, 0, 0, dg,
+                   0, 0, 2, 0, db,
+                   0, 0, 0, 1, da });
+        }
+        
+        private static void setContrast(ColorMatrix cm, float contrast) {
+            float scale = contrast + 1.f;
+               float translate = (-.5f * scale + .5f) * 255.f;
+            cm.set(new float[] {
+                   scale, 0, 0, 0, translate,
+                   0, scale, 0, 0, translate,
+                   0, 0, scale, 0, translate,
+                   0, 0, 0, 1, 0 });
+        }
+        
+        private static void setContrastTranslateOnly(ColorMatrix cm, float contrast) {
+            float scale = contrast + 1.f;
+               float translate = (-.5f * scale + .5f) * 255.f;
+            cm.set(new float[] {
+                   1, 0, 0, 0, translate,
+                   0, 1, 0, 0, translate,
+                   0, 0, 1, 0, translate,
+                   0, 0, 0, 1, 0 });
+        }
+        
+        private static void setContrastScaleOnly(ColorMatrix cm, float contrast) {
+            float scale = contrast + 1.f;
+               float translate = (-.5f * scale + .5f) * 255.f;
+            cm.set(new float[] {
+                   scale, 0, 0, 0, 0,
+                   0, scale, 0, 0, 0,
+                   0, 0, scale, 0, 0,
+                   0, 0, 0, 1, 0 });
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+            float x = 20;
+            float y = 20;
+            
+            canvas.drawColor(Color.WHITE);
+            
+            paint.setColorFilter(null);
+            canvas.drawBitmap(mBitmap, x, y, paint);
+            
+            ColorMatrix cm = new ColorMatrix();
+            
+            mAngle += 2;
+            if (mAngle > 180) {
+                mAngle = 0;
+            }
+            
+            //convert our animated angle [-180...180] to a contrast value of [-1..1]
+            float contrast = mAngle / 180.f;
+            
+            setContrast(cm, contrast);
+            paint.setColorFilter(new ColorMatrixColorFilter(cm));
+            canvas.drawBitmap(mBitmap, x + mBitmap.getWidth() + 10, y, paint);
+            
+            setContrastScaleOnly(cm, contrast);
+            paint.setColorFilter(new ColorMatrixColorFilter(cm));
+            canvas.drawBitmap(mBitmap, x, y + mBitmap.getHeight() + 10, paint);
+            
+            setContrastTranslateOnly(cm, contrast);
+            paint.setColorFilter(new ColorMatrixColorFilter(cm));
+            canvas.drawBitmap(mBitmap, x, y + 2*(mBitmap.getHeight() + 10),
+                              paint);
+            
+            invalidate();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
new file mode 100644
index 0000000..cc4a0d4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.R;
+import android.os.Bundle;
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.*;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class ColorPickerDialog extends Dialog {
+
+    public interface OnColorChangedListener {
+        void colorChanged(int color);
+    }
+
+    private OnColorChangedListener mListener;
+    private int mInitialColor;
+
+    private static class ColorPickerView extends View {
+        private Paint mPaint;
+        private Paint mCenterPaint;
+        private final int[] mColors;
+        private OnColorChangedListener mListener;
+        
+        ColorPickerView(Context c, OnColorChangedListener l, int color) {
+            super(c);
+            mListener = l;
+            mColors = new int[] {
+                0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
+                0xFFFFFF00, 0xFFFF0000
+            };
+            Shader s = new SweepGradient(0, 0, mColors, null);
+            
+            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mPaint.setShader(s);
+            mPaint.setStyle(Paint.Style.STROKE);
+            mPaint.setStrokeWidth(32);
+            
+            mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mCenterPaint.setColor(color);
+            mCenterPaint.setStrokeWidth(5);
+        }
+        
+        private boolean mTrackingCenter;
+        private boolean mHighlightCenter;
+
+        @Override 
+        protected void onDraw(Canvas canvas) {
+            float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
+            
+            canvas.translate(CENTER_X, CENTER_X);
+            
+            canvas.drawOval(new RectF(-r, -r, r, r), mPaint);            
+            canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
+            
+            if (mTrackingCenter) {
+                int c = mCenterPaint.getColor();
+                mCenterPaint.setStyle(Paint.Style.STROKE);
+                
+                if (mHighlightCenter) {
+                    mCenterPaint.setAlpha(0xFF);
+                } else {
+                    mCenterPaint.setAlpha(0x80);
+                }
+                canvas.drawCircle(0, 0,
+                                  CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
+                                  mCenterPaint);
+                
+                mCenterPaint.setStyle(Paint.Style.FILL);
+                mCenterPaint.setColor(c);
+            }
+        }
+        
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
+        }
+        
+        private static final int CENTER_X = 100;
+        private static final int CENTER_Y = 100;
+        private static final int CENTER_RADIUS = 32;
+
+        private int floatToByte(float x) {
+            int n = java.lang.Math.round(x);
+            return n;
+        }
+        private int pinToByte(int n) {
+            if (n < 0) {
+                n = 0;
+            } else if (n > 255) {
+                n = 255;
+            }
+            return n;
+        }
+        
+        private int ave(int s, int d, float p) {
+            return s + java.lang.Math.round(p * (d - s));
+        }
+        
+        private int interpColor(int colors[], float unit) {
+            if (unit <= 0) {
+                return colors[0];
+            }
+            if (unit >= 1) {
+                return colors[colors.length - 1];
+            }
+            
+            float p = unit * (colors.length - 1);
+            int i = (int)p;
+            p -= i;
+
+            // now p is just the fractional part [0...1) and i is the index
+            int c0 = colors[i];
+            int c1 = colors[i+1];
+            int a = ave(Color.alpha(c0), Color.alpha(c1), p);
+            int r = ave(Color.red(c0), Color.red(c1), p);
+            int g = ave(Color.green(c0), Color.green(c1), p);
+            int b = ave(Color.blue(c0), Color.blue(c1), p);
+            
+            return Color.argb(a, r, g, b);
+        }
+        
+        private int rotateColor(int color, float rad) {
+            float deg = rad * 180 / 3.1415927f;
+            int r = Color.red(color);
+            int g = Color.green(color);
+            int b = Color.blue(color);
+            
+            ColorMatrix cm = new ColorMatrix();
+            ColorMatrix tmp = new ColorMatrix();
+
+            cm.setRGB2YUV();
+            tmp.setRotate(0, deg);
+            cm.postConcat(tmp);
+            tmp.setYUV2RGB();
+            cm.postConcat(tmp);
+            
+            final float[] a = cm.getArray();
+
+            int ir = floatToByte(a[0] * r +  a[1] * g +  a[2] * b);
+            int ig = floatToByte(a[5] * r +  a[6] * g +  a[7] * b);
+            int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
+            
+            return Color.argb(Color.alpha(color), pinToByte(ir),
+                              pinToByte(ig), pinToByte(ib));
+        }
+        
+        private static final float PI = 3.1415926f;
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            float x = event.getX() - CENTER_X;
+            float y = event.getY() - CENTER_Y;
+            boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
+            
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    mTrackingCenter = inCenter;
+                    if (inCenter) {
+                        mHighlightCenter = true;
+                        invalidate();
+                        break;
+                    }
+                case MotionEvent.ACTION_MOVE:
+                    if (mTrackingCenter) {
+                        if (mHighlightCenter != inCenter) {
+                            mHighlightCenter = inCenter;
+                            invalidate();
+                        }
+                    } else {
+                        float angle = (float)java.lang.Math.atan2(y, x);
+                        // need to turn angle [-PI ... PI] into unit [0....1]
+                        float unit = angle/(2*PI);
+                        if (unit < 0) {
+                            unit += 1;
+                        }
+                        mCenterPaint.setColor(interpColor(mColors, unit));
+                        invalidate();
+                    }
+                    break;
+                case MotionEvent.ACTION_UP:
+                    if (mTrackingCenter) {
+                        if (inCenter) {
+                            mListener.colorChanged(mCenterPaint.getColor());
+                        }
+                        mTrackingCenter = false;    // so we draw w/o halo
+                        invalidate();
+                    }
+                    break;
+            }
+            return true;
+        }
+    }
+
+    public ColorPickerDialog(Context context,
+                             OnColorChangedListener listener,
+                             int initialColor) {
+        super(context);
+        
+        mListener = listener;
+        mInitialColor = initialColor;
+    }
+
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        OnColorChangedListener l = new OnColorChangedListener() {
+            public void colorChanged(int color) {
+                mListener.colorChanged(color);
+                dismiss();
+            }
+        };
+
+        setContentView(new ColorPickerView(getContext(), l, mInitialColor));
+        setTitle("Pick a Color");
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
new file mode 100644
index 0000000..d2a9907
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.hardware.SensorListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Config;
+import android.util.Log;
+import android.view.View;
+
+public class Compass extends GraphicsActivity {
+
+    private static final String TAG = "Compass";
+
+	private SensorManager mSensorManager;
+    private SampleView mView;
+    private float[] mValues;
+    
+    private final SensorListener mListener = new SensorListener() {
+    
+        public void onSensorChanged(int sensor, float[] values) {
+            if (Config.LOGD) Log.d(TAG, "sensorChanged (" + values[0] + ", " + values[1] + ", " + values[2] + ")");
+            mValues = values;
+            if (mView != null) {
+                mView.invalidate();
+            }
+        }
+
+        public void onAccuracyChanged(int sensor, int accuracy) {
+            // TODO Auto-generated method stub
+            
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
+        mView = new SampleView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume()
+    {
+        if (Config.LOGD) Log.d(TAG, "onResume");
+        super.onResume();
+        mSensorManager.registerListener(mListener, 
+        		SensorManager.SENSOR_ORIENTATION,
+        		SensorManager.SENSOR_DELAY_GAME);
+    }
+    
+    @Override
+    protected void onStop()
+    {
+        if (Config.LOGD) Log.d(TAG, "onStop");
+        mSensorManager.unregisterListener(mListener);
+        super.onStop();
+    }
+
+    private class SampleView extends View {
+        private Paint   mPaint = new Paint();
+        private Path    mPath = new Path();
+        private boolean mAnimate;
+        private long    mNextTime;
+
+        public SampleView(Context context) {
+            super(context);
+
+            // Construct a wedge-shaped path
+            mPath.moveTo(0, -50);
+            mPath.lineTo(-20, 60);
+            mPath.lineTo(0, 50);
+            mPath.lineTo(20, 60);
+            mPath.close();
+        }
+    
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+
+            canvas.drawColor(Color.WHITE);
+            
+            paint.setAntiAlias(true);
+            paint.setColor(Color.BLACK);
+            paint.setStyle(Paint.Style.FILL);
+
+            int w = canvas.getWidth();
+            int h = canvas.getHeight();
+            int cx = w / 2;
+            int cy = h / 2;
+
+            canvas.translate(cx, cy);
+            if (mValues != null) {            
+                canvas.rotate(-mValues[0]);
+            }
+            canvas.drawPath(mPath, mPaint);
+        }
+    
+        @Override
+        protected void onAttachedToWindow() {
+            mAnimate = true;
+            super.onAttachedToWindow();
+        }
+        
+        @Override
+        protected void onDetachedFromWindow() {
+            mAnimate = false;
+            super.onDetachedFromWindow();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
new file mode 100644
index 0000000..e3e5d9a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+import java.io.ByteArrayOutputStream;
+
+public class CreateBitmap extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static final int WIDTH = 50;
+    private static final int HEIGHT = 50;
+    private static final int STRIDE = 64;   // must be >= WIDTH
+    
+    private static int[] createColors() {
+        int[] colors = new int[STRIDE * HEIGHT];
+        for (int y = 0; y < HEIGHT; y++) {
+            for (int x = 0; x < WIDTH; x++) {
+                int r = x * 255 / (WIDTH - 1);
+                int g = y * 255 / (HEIGHT - 1);
+                int b = 255 - Math.min(r, g);
+                int a = Math.max(r, g);
+                colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
+            }
+        }
+        return colors;
+    }
+        
+    private static class SampleView extends View {
+        private Bitmap[] mBitmaps;
+        private Bitmap[] mJPEG;
+        private Bitmap[] mPNG;
+        private int[]    mColors;
+        private Paint    mPaint;
+        
+        private static Bitmap codec(Bitmap src, Bitmap.CompressFormat format,
+                                    int quality) {
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            src.compress(format, quality, os);            
+
+            byte[] array = os.toByteArray();
+            return BitmapFactory.decodeByteArray(array, 0, array.length);
+        }
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            mColors = createColors();
+            int[] colors = mColors;
+
+            mBitmaps = new Bitmap[6];
+            // these three are initialized with colors[]
+            mBitmaps[0] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
+                                              Bitmap.Config.ARGB_8888);
+            mBitmaps[1] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
+                                              Bitmap.Config.RGB_565);
+            mBitmaps[2] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
+                                              Bitmap.Config.ARGB_4444);
+            
+            // these three will have their colors set later
+            mBitmaps[3] = Bitmap.createBitmap(WIDTH, HEIGHT,
+                                              Bitmap.Config.ARGB_8888);
+            mBitmaps[4] = Bitmap.createBitmap(WIDTH, HEIGHT,
+                                              Bitmap.Config.RGB_565);
+            mBitmaps[5] = Bitmap.createBitmap(WIDTH, HEIGHT,
+                                              Bitmap.Config.ARGB_4444);
+            for (int i = 3; i <= 5; i++) {
+                mBitmaps[i].setPixels(colors, 0, STRIDE, 0, 0, WIDTH, HEIGHT);
+            }
+            
+            mPaint = new Paint();
+            mPaint.setDither(true);
+            
+            // now encode/decode using JPEG and PNG
+            mJPEG = new Bitmap[mBitmaps.length];
+            mPNG = new Bitmap[mBitmaps.length];
+            for (int i = 0; i < mBitmaps.length; i++) {
+                mJPEG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.JPEG, 80);
+                mPNG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.PNG, 0);
+            }
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+
+            for (int i = 0; i < mBitmaps.length; i++) {
+                canvas.drawBitmap(mBitmaps[i], 0, 0, null);
+                canvas.drawBitmap(mJPEG[i], 80, 0, null);
+                canvas.drawBitmap(mPNG[i], 160, 0, null);
+                canvas.translate(0, mBitmaps[i].getHeight());
+            }
+            
+            // draw the color array directly, w/o craeting a bitmap object
+            canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT,
+                              true, null);
+            canvas.translate(0, HEIGHT);
+            canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT,
+                              false, mPaint);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
new file mode 100644
index 0000000..bb154eb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A vertex shaded cube.
+ */
+class Cube
+{
+    public Cube()
+    {
+        int one = 0x10000;
+        int vertices[] = {
+                -one, -one, -one,
+                one, -one, -one,
+                one,  one, -one,
+                -one,  one, -one,
+                -one, -one,  one,
+                one, -one,  one,
+                one,  one,  one,
+                -one,  one,  one,
+        };
+
+        int colors[] = {
+                0,    0,    0,  one,
+                one,    0,    0,  one,
+                one,  one,    0,  one,
+                0,  one,    0,  one,
+                0,    0,  one,  one,
+                one,    0,  one,  one,
+                one,  one,  one,  one,
+                0,  one,  one,  one,
+        };
+
+        byte indices[] = {
+                0, 4, 5,    0, 5, 1,
+                1, 5, 6,    1, 6, 2,
+                2, 6, 7,    2, 7, 3,
+                3, 7, 4,    3, 4, 0,
+                4, 7, 6,    4, 6, 5,
+                3, 0, 1,    3, 1, 2
+        };
+
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct, i.e., they must be placed on the
+        // native heap where the garbage collector cannot
+        // move them.
+        //
+        // Buffers with multi-byte datatypes (e.g., short, int, float)
+        // must have their byte order set to native order
+
+        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
+        vbb.order(ByteOrder.nativeOrder());
+        mVertexBuffer = vbb.asIntBuffer();
+        mVertexBuffer.put(vertices);
+        mVertexBuffer.position(0);
+
+        ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
+        cbb.order(ByteOrder.nativeOrder());
+        mColorBuffer = cbb.asIntBuffer();
+        mColorBuffer.put(colors);
+        mColorBuffer.position(0);
+
+        mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
+        mIndexBuffer.put(indices);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl)
+    {
+        gl.glFrontFace(gl.GL_CW);
+        gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
+        gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
+        gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
+    }
+
+    private IntBuffer   mVertexBuffer;
+    private IntBuffer   mColorBuffer;
+    private ByteBuffer  mIndexBuffer;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
new file mode 100644
index 0000000..527e2bc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLSurfaceView;
+
+/**
+ * Render a pair of tumbling cubes.
+ */
+
+class CubeRenderer implements GLSurfaceView.Renderer {
+    public CubeRenderer(boolean useTranslucentBackground) {
+        mTranslucentBackground = useTranslucentBackground;
+        mCube = new Cube();
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(0, 0, -3.0f);
+        gl.glRotatef(mAngle,        0, 1, 0);
+        gl.glRotatef(mAngle*0.25f,  1, 0, 0);
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+        mCube.draw(gl);
+
+        gl.glRotatef(mAngle*2.0f, 0, 1, 1);
+        gl.glTranslatef(0.5f, 0.5f, 0.5f);
+
+        mCube.draw(gl);
+
+        mAngle += 1.2f;
+    }
+
+    public int[] getConfigSpec() {
+        if (mTranslucentBackground) {
+                // We want a depth buffer and an alpha buffer
+                int[] configSpec = {
+                        EGL10.EGL_RED_SIZE,      8,
+                        EGL10.EGL_GREEN_SIZE,    8,
+                        EGL10.EGL_BLUE_SIZE,     8,
+                        EGL10.EGL_ALPHA_SIZE,    8,
+                        EGL10.EGL_DEPTH_SIZE,   16,
+                        EGL10.EGL_NONE
+                };
+                return configSpec;
+            } else {
+                // We want a depth buffer, don't care about the
+                // details of the color buffer.
+                int[] configSpec = {
+                        EGL10.EGL_DEPTH_SIZE,   16,
+                        EGL10.EGL_NONE
+                };
+                return configSpec;
+            }
+    }
+
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+         gl.glViewport(0, 0, width, height);
+
+         /*
+          * Set our projection matrix. This doesn't have to be done
+          * each time we draw, but usually a new projection needs to
+          * be set when the viewport is resized.
+          */
+
+         float ratio = (float) width / height;
+         gl.glMatrixMode(GL10.GL_PROJECTION);
+         gl.glLoadIdentity();
+         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                 GL10.GL_FASTEST);
+
+         if (mTranslucentBackground) {
+             gl.glClearColor(0,0,0,0);
+         } else {
+             gl.glClearColor(1,1,1,1);
+         }
+         gl.glEnable(GL10.GL_CULL_FACE);
+         gl.glShadeModel(GL10.GL_SMOOTH);
+         gl.glEnable(GL10.GL_DEPTH_TEST);
+    }
+    private boolean mTranslucentBackground;
+    private Cube mCube;
+    private float mAngle;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java b/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
new file mode 100644
index 0000000..cbe6373
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class DrawPoints extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint   mPaint = new Paint();
+        private float[] mPts;
+
+        private static final float SIZE = 300;
+        private static final int SEGS = 32;
+        private static final int X = 0;
+        private static final int Y = 1;
+        
+        private void buildPoints() {
+            final int ptCount = (SEGS + 1) * 2;
+            mPts = new float[ptCount * 2];
+            
+            float value = 0;
+            final float delta = SIZE / SEGS;
+            for (int i = 0; i <= SEGS; i++) {
+                mPts[i*4 + X] = SIZE - value;
+                mPts[i*4 + Y] = 0;
+                mPts[i*4 + X + 2] = 0;
+                mPts[i*4 + Y + 2] = value;
+                value += delta;
+            }
+        }
+    
+        public SampleView(Context context) {
+            super(context);
+            
+            buildPoints();
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+            
+            canvas.translate(10, 10);
+
+            canvas.drawColor(Color.WHITE);
+
+            paint.setColor(Color.RED);
+            paint.setStrokeWidth(0);
+            canvas.drawLines(mPts, paint);
+            
+            paint.setColor(Color.BLUE);
+            paint.setStrokeWidth(3);
+            canvas.drawPoints(mPts, paint);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
new file mode 100644
index 0000000..867da4c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class FingerPaint extends GraphicsActivity
+        implements ColorPickerDialog.OnColorChangedListener {    
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new MyView(this));
+
+        mPaint = new Paint();
+        mPaint.setAntiAlias(true);
+        mPaint.setDither(true);
+        mPaint.setColor(0xFFFF0000);
+        mPaint.setStyle(Paint.Style.STROKE);
+        mPaint.setStrokeJoin(Paint.Join.ROUND);
+        mPaint.setStrokeCap(Paint.Cap.ROUND);
+        mPaint.setStrokeWidth(12);
+        
+        mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
+                                       0.4f, 6, 3.5f);
+
+        mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
+    }
+    
+    private Paint       mPaint;
+    private MaskFilter  mEmboss;
+    private MaskFilter  mBlur;
+    
+    public void colorChanged(int color) {
+        mPaint.setColor(color);
+    }
+
+    public class MyView extends View {
+        
+        private static final float MINP = 0.25f;
+        private static final float MAXP = 0.75f;
+        
+        private Bitmap  mBitmap;
+        private Canvas  mCanvas;
+        private Path    mPath;
+        private Paint   mBitmapPaint;
+        
+        public MyView(Context c) {
+            super(c);
+            
+            mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
+            mCanvas = new Canvas(mBitmap);
+            mPath = new Path();
+            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
+        }
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+        }
+        
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.drawColor(0xFFAAAAAA);
+            
+            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
+            
+            canvas.drawPath(mPath, mPaint);
+        }
+        
+        private float mX, mY;
+        private static final float TOUCH_TOLERANCE = 4;
+        
+        private void touch_start(float x, float y) {
+            mPath.reset();
+            mPath.moveTo(x, y);
+            mX = x;
+            mY = y;
+        }
+        private void touch_move(float x, float y) {
+            float dx = Math.abs(x - mX);
+            float dy = Math.abs(y - mY);
+            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
+                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
+                mX = x;
+                mY = y;
+            }
+        }
+        private void touch_up() {
+            mPath.lineTo(mX, mY);
+            // commit the path to our offscreen
+            mCanvas.drawPath(mPath, mPaint);
+            // kill this so we don't double draw
+            mPath.reset();
+        }
+        
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            float x = event.getX();
+            float y = event.getY();
+            
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    touch_start(x, y);
+                    invalidate();
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    touch_move(x, y);
+                    invalidate();
+                    break;
+                case MotionEvent.ACTION_UP:
+                    touch_up();
+                    invalidate();
+                    break;
+            }
+            return true;
+        }
+    }
+    
+    private static final int COLOR_MENU_ID = Menu.FIRST;
+    private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
+    private static final int BLUR_MENU_ID = Menu.FIRST + 2;
+    private static final int ERASE_MENU_ID = Menu.FIRST + 3;
+    private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
+        menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
+        menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
+        menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
+        menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
+
+        /****   Is this the mechanism to extend with filter effects?
+        Intent intent = new Intent(null, getIntent().getData());
+        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+        menu.addIntentOptions(
+                              Menu.ALTERNATIVE, 0,
+                              new ComponentName(this, NotesList.class),
+                              null, intent, 0, null);
+        *****/
+        return true;
+    }
+    
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        return true;
+    }
+    
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        mPaint.setXfermode(null);
+        mPaint.setAlpha(0xFF);
+
+        switch (item.getItemId()) {
+            case COLOR_MENU_ID:
+                new ColorPickerDialog(this, this, mPaint.getColor()).show();
+                return true;
+            case EMBOSS_MENU_ID:
+                if (mPaint.getMaskFilter() != mEmboss) {
+                    mPaint.setMaskFilter(mEmboss);
+                } else {
+                    mPaint.setMaskFilter(null);
+                }
+                return true;
+            case BLUR_MENU_ID:
+                if (mPaint.getMaskFilter() != mBlur) {
+                    mPaint.setMaskFilter(mBlur);
+                } else {
+                    mPaint.setMaskFilter(null);
+                }
+                return true;
+            case ERASE_MENU_ID:
+                mPaint.setXfermode(new PorterDuffXfermode(
+                                                        PorterDuff.Mode.CLEAR));
+                return true;
+            case SRCATOP_MENU_ID:
+                mPaint.setXfermode(new PorterDuffXfermode(
+                                                    PorterDuff.Mode.SRC_ATOP));
+                mPaint.setAlpha(0x80);
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GLSurfaceViewActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GLSurfaceViewActivity.java
new file mode 100644
index 0000000..f852186
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GLSurfaceViewActivity.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+/**
+ * Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view
+ * that uses OpenGL drawing into a dedicated surface.
+ */
+public class GLSurfaceViewActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mGLSurfaceView = new GLSurfaceView(this);
+        mGLSurfaceView.setRenderer(new CubeRenderer(false));
+        setContentView(mGLSurfaceView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mGLSurfaceView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mGLSurfaceView.onPause();
+    }
+
+    private GLSurfaceView mGLSurfaceView;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
new file mode 100644
index 0000000..eb6d47d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class GradientDrawable1 extends GraphicsActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.shape_drawable_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
new file mode 100644
index 0000000..023c0d7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+
+class GraphicsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void setContentView(View view) {
+        if (false) { // set to true to test Picture
+            ViewGroup vg = new PictureLayout(this);
+            vg.addView(view);
+            view = vg;
+        }
+        
+        super.setContentView(view);
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
new file mode 100644
index 0000000..d9f5db0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.*;
+
+public class Layers extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG |
+                                            Canvas.CLIP_SAVE_FLAG |
+                                            Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
+                                            Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
+                                            Canvas.CLIP_TO_LAYER_SAVE_FLAG;
+
+        private Paint mPaint;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);            
+            
+            canvas.translate(10, 10);
+            
+            canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);
+            
+            mPaint.setColor(Color.RED);
+            canvas.drawCircle(75, 75, 75, mPaint);
+            mPaint.setColor(Color.BLUE);
+            canvas.drawCircle(125, 125, 75, mPaint);
+            
+            canvas.restore();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java b/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
new file mode 100644
index 0000000..e159efe
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+public class MeasureText extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static final int WIDTH = 50;
+    private static final int HEIGHT = 50;
+    private static final int STRIDE = 64;   // must be >= WIDTH
+    
+    private static int[] createColors() {
+        int[] colors = new int[STRIDE * HEIGHT];
+        for (int y = 0; y < HEIGHT; y++) {
+            for (int x = 0; x < WIDTH; x++) {
+                int r = x * 255 / (WIDTH - 1);
+                int g = y * 255 / (HEIGHT - 1);
+                int b = 255 - Math.min(r, g);
+                int a = Math.max(r, g);
+                colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
+            }
+        }
+        return colors;
+    }
+    
+    private static class SampleView extends View {
+        private Paint   mPaint;
+        private float   mOriginX = 10;
+        private float   mOriginY = 80;
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setStrokeWidth(5);
+            mPaint.setStrokeCap(Paint.Cap.ROUND);
+            mPaint.setTextSize(64);
+            mPaint.setTypeface(Typeface.create(Typeface.SERIF,
+                                               Typeface.ITALIC));
+        }
+        
+        private void showText(Canvas canvas, String text, Paint.Align align) {
+         //   mPaint.setTextAlign(align);
+            
+            Rect    bounds = new Rect();
+            float[] widths = new float[text.length()];
+
+            int count = mPaint.getTextWidths(text, 0, text.length(), widths);
+            float w = mPaint.measureText(text, 0, text.length());
+            mPaint.getTextBounds(text, 0, text.length(), bounds);
+            
+            mPaint.setColor(0xFF88FF88);
+            canvas.drawRect(bounds, mPaint);
+            mPaint.setColor(Color.BLACK);
+            canvas.drawText(text, 0, 0, mPaint);
+            
+            float[] pts = new float[2 + count*2];
+            float x = 0;
+            float y = 0;
+            pts[0] = x;
+            pts[1] = y;
+            for (int i = 0; i < count; i++) {
+                x += widths[i];
+                pts[2 + i*2] = x;
+                pts[2 + i*2 + 1] = y;
+            }
+            mPaint.setColor(Color.RED);
+            mPaint.setStrokeWidth(0);
+            canvas.drawLine(0, 0, w, 0, mPaint);
+            mPaint.setStrokeWidth(5);
+            canvas.drawPoints(pts, 0, (count + 1) << 1, mPaint);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+            
+            canvas.translate(mOriginX, mOriginY);
+            
+            showText(canvas, "Measure", Paint.Align.LEFT);
+            canvas.translate(0, 80);
+            showText(canvas, "wiggy!", Paint.Align.CENTER);
+            canvas.translate(0, 80);
+            showText(canvas, "Text", Paint.Align.RIGHT);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
new file mode 100644
index 0000000..80ddf38
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+public class PathEffects extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint mPaint;
+        private Path mPath;
+        private PathEffect[] mEffects;
+        private int[] mColors;
+        private float mPhase;
+
+        private static PathEffect makeDash(float phase) {
+            return new DashPathEffect(new float[] { 15, 5, 8, 5 }, phase);
+        }
+        
+        private static void makeEffects(PathEffect[] e, float phase) {
+            e[0] = null;     // no effect
+            e[1] = new CornerPathEffect(10);
+            e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
+            e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
+                                          PathDashPathEffect.Style.ROTATE);
+            e[4] = new ComposePathEffect(e[2], e[1]);
+            e[5] = new ComposePathEffect(e[3], e[1]);
+        }
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+
+            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mPaint.setStyle(Paint.Style.STROKE);
+            mPaint.setStrokeWidth(6);
+            
+            mPath = makeFollowPath();
+            
+            mEffects = new PathEffect[6];
+            
+            mColors = new int[] { Color.BLACK, Color.RED, Color.BLUE,
+                                  Color.GREEN, Color.MAGENTA, Color.BLACK
+                                };
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+            
+            RectF bounds = new RectF();
+            mPath.computeBounds(bounds, false);
+            canvas.translate(10 - bounds.left, 10 - bounds.top);
+            
+            makeEffects(mEffects, mPhase);
+            mPhase += 1;
+            invalidate();
+
+            for (int i = 0; i < mEffects.length; i++) {
+                mPaint.setPathEffect(mEffects[i]);
+                mPaint.setColor(mColors[i]);
+                canvas.drawPath(mPath, mPaint);
+                canvas.translate(0, 28);
+            }
+        }
+        
+        @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_DPAD_CENTER:
+                    mPath = makeFollowPath();
+                    return true;
+            }
+            return super.onKeyDown(keyCode, event);
+        }
+
+        private static Path makeFollowPath() {
+            Path p = new Path();
+            p.moveTo(0, 0);
+            for (int i = 1; i <= 15; i++) {
+                p.lineTo(i*20, (float)Math.random() * 35);
+            }
+            return p;
+        }
+        
+        private static Path makePathDash() {
+            Path p = new Path();
+            p.moveTo(4, 0);
+            p.lineTo(0, -4);
+            p.lineTo(8, -4);
+            p.lineTo(12, 0);
+            p.lineTo(8, 4);
+            p.lineTo(0, 4);
+            return p;
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
new file mode 100644
index 0000000..78dba26
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+//import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+public class PathFillTypes extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private Path mPath;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+
+            mPath = new Path();
+            mPath.addCircle(40, 40, 45, Path.Direction.CCW);
+            mPath.addCircle(80, 80, 45, Path.Direction.CCW);
+        }
+        
+        private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
+                              Paint paint) {
+            canvas.save();
+            canvas.translate(x, y);
+            canvas.clipRect(0, 0, 120, 120);
+            canvas.drawColor(Color.WHITE);
+            mPath.setFillType(ft);
+            canvas.drawPath(mPath, paint);
+            canvas.restore();
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+
+            canvas.drawColor(0xFFCCCCCC);
+            
+            canvas.translate(20, 20);
+            
+            paint.setAntiAlias(true);
+
+            showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
+            showPath(canvas, 160, 0, Path.FillType.EVEN_ODD, paint);
+            showPath(canvas, 0, 160, Path.FillType.INVERSE_WINDING, paint);
+            showPath(canvas, 160, 160, Path.FillType.INVERSE_EVEN_ODD, paint);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
new file mode 100644
index 0000000..d2a51ff
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.*;
+
+public class Patterns extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static Bitmap makeBitmap1() {
+        Bitmap bm = Bitmap.createBitmap(40, 40, Bitmap.Config.RGB_565);
+        Canvas c = new Canvas(bm);
+        c.drawColor(Color.RED);
+        Paint p = new Paint();
+        p.setColor(Color.BLUE);
+        c.drawRect(5, 5, 35, 35, p);
+        return bm;
+    }
+    
+    private static Bitmap makeBitmap2() {
+        Bitmap bm = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas(bm);
+        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+        p.setColor(Color.GREEN);
+        p.setAlpha(0xCC);
+        c.drawCircle(32, 32, 27, p);
+        return bm;
+    }
+    
+    private static class SampleView extends View {
+        private final Shader mShader1;
+        private final Shader mShader2;
+        private final Paint mPaint;
+        private final DrawFilter mFastDF;
+        
+        private float mTouchStartX;
+        private float mTouchStartY;
+        private float mTouchCurrX;
+        private float mTouchCurrY;
+        private DrawFilter mDF;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+
+            mFastDF = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG |
+                                               Paint.DITHER_FLAG,
+                                               0);
+    
+            mShader1 = new BitmapShader(makeBitmap1(), Shader.TileMode.REPEAT,
+                                        Shader.TileMode.REPEAT);
+            mShader2 = new BitmapShader(makeBitmap2(), Shader.TileMode.REPEAT,
+                                        Shader.TileMode.REPEAT);
+            
+            Matrix m = new Matrix();
+            m.setRotate(30);
+            mShader2.setLocalMatrix(m);
+            
+            mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.setDrawFilter(mDF);
+
+            mPaint.setShader(mShader1);
+            canvas.drawPaint(mPaint);
+            
+            canvas.translate(mTouchCurrX - mTouchStartX,
+                             mTouchCurrY - mTouchStartY);
+
+            mPaint.setShader(mShader2);
+            canvas.drawPaint(mPaint);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            float x = event.getX();
+            float y = event.getY();
+            
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    mTouchStartX = mTouchCurrX = x;
+                    mTouchStartY = mTouchCurrY = y;
+                    mDF = mFastDF;
+                    invalidate();
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    mTouchCurrX = x;
+                    mTouchCurrY = y;
+                    invalidate();
+                    break;
+                case MotionEvent.ACTION_UP:
+                    mDF = null;
+                    invalidate();
+                    break;
+            }
+            return true;
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
new file mode 100644
index 0000000..9bdb49a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Picture;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+
+public class PictureLayout extends ViewGroup {
+    private final Picture mPicture = new Picture();
+
+    public PictureLayout(Context context) {
+        super(context);
+    }
+
+    public PictureLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }    
+
+    @Override
+    public void addView(View child) {
+        if (getChildCount() > 1) {
+            throw new IllegalStateException("PictureLayout can host only one direct child");
+        }
+
+        super.addView(child);
+    }
+
+    @Override
+    public void addView(View child, int index) {
+        if (getChildCount() > 1) {
+            throw new IllegalStateException("PictureLayout can host only one direct child");
+        }
+
+        super.addView(child, index);
+    }
+
+    @Override
+    public void addView(View child, LayoutParams params) {
+        if (getChildCount() > 1) {
+            throw new IllegalStateException("PictureLayout can host only one direct child");
+        }
+
+        super.addView(child, params);
+    }
+
+    @Override
+    public void addView(View child, int index, LayoutParams params) {
+        if (getChildCount() > 1) {
+            throw new IllegalStateException("PictureLayout can host only one direct child");
+        }
+
+        super.addView(child, index, params);
+    }
+
+    @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int count = getChildCount();
+
+        int maxHeight = 0;
+        int maxWidth = 0;
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                measureChild(child, widthMeasureSpec, heightMeasureSpec);
+            }
+        }
+
+        maxWidth += getPaddingLeft() + getPaddingRight();
+        maxHeight += getPaddingTop() + getPaddingBottom();
+
+        Drawable drawable = getBackground();
+        if (drawable != null) {
+            maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+            maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+        }
+
+        setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
+                resolveSize(maxHeight, heightMeasureSpec));
+    }
+    
+    private void drawPict(Canvas canvas, int x, int y, int w, int h,
+                          float sx, float sy) {
+        canvas.save();
+        canvas.translate(x, y);
+        canvas.clipRect(0, 0, w, h);
+        canvas.scale(0.5f, 0.5f);
+        canvas.scale(sx, sy, w, h);
+        canvas.drawPicture(mPicture);
+        canvas.restore();
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
+        mPicture.endRecording();
+        
+        int x = getWidth()/2;
+        int y = getHeight()/2;
+        
+        if (false) {
+            canvas.drawPicture(mPicture);
+        } else {
+            drawPict(canvas, 0, 0, x, y,  1,  1);
+            drawPict(canvas, x, 0, x, y, -1,  1);
+            drawPict(canvas, 0, y, x, y,  1, -1);
+            drawPict(canvas, x, y, x, y, -1, -1);
+        }
+    }
+
+    @Override
+    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
+        location[0] = getLeft();
+        location[1] = getTop();
+        dirty.set(0, 0, getWidth(), getHeight());
+        return getParent();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int count = super.getChildCount();
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                final int childLeft = getPaddingLeft();
+                final int childTop = getPaddingTop();
+                child.layout(childLeft, childTop,
+                        childLeft + child.getMeasuredWidth(),
+                        childTop + child.getMeasuredHeight());
+
+            }
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
new file mode 100644
index 0000000..1bd0a8c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.PictureDrawable;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+import java.io.*;
+
+public class Pictures extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Picture mPicture;
+        private Drawable mDrawable;
+
+        static void drawSomething(Canvas canvas) {
+            Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+            
+            p.setColor(0x88FF0000);
+            canvas.drawCircle(50, 50, 40, p);
+            
+            p.setColor(Color.GREEN);
+            p.setTextSize(30);
+            canvas.drawText("Pictures", 60, 60, p);
+        }
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+
+            mPicture = new Picture();
+            drawSomething(mPicture.beginRecording(200, 100));
+            mPicture.endRecording();
+            
+            mDrawable = new PictureDrawable(mPicture);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+
+            canvas.drawPicture(mPicture);
+            
+            canvas.drawPicture(mPicture, new RectF(0, 100, getWidth(), 200));
+            
+            mDrawable.setBounds(0, 200, getWidth(), 300);
+            mDrawable.draw(canvas);
+            
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            mPicture.writeToStream(os);
+            InputStream is = new ByteArrayInputStream(os.toByteArray());
+            canvas.translate(0, 300);
+            canvas.drawPicture(Picture.createFromStream(is));
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
new file mode 100644
index 0000000..15d92de
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+//import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class PolyToPoly extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private Matrix  mMatrix = new Matrix();
+        private Paint.FontMetrics mFontMetrics;
+
+        private void doDraw(Canvas canvas, float src[], float dst[]) {
+            canvas.save();
+            mMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
+            canvas.concat(mMatrix);
+            
+            mPaint.setColor(Color.GRAY);
+            mPaint.setStyle(Paint.Style.STROKE);
+            canvas.drawRect(0, 0, 64, 64, mPaint);
+            canvas.drawLine(0, 0, 64, 64, mPaint);
+            canvas.drawLine(0, 64, 64, 0, mPaint);
+            
+            mPaint.setColor(Color.RED);
+            mPaint.setStyle(Paint.Style.FILL);
+            // how to draw the text center on our square
+            // centering in X is easy... use alignment (and X at midpoint)
+            float x = 64/2;
+            // centering in Y, we need to measure ascent/descent first
+            float y = 64/2 - (mFontMetrics.ascent + mFontMetrics.descent)/2;
+            canvas.drawText(src.length/2 + "", x, y, mPaint);
+            
+            canvas.restore();
+        }
+
+        public SampleView(Context context) {
+            super(context);
+
+            // for when the style is STROKE
+            mPaint.setStrokeWidth(4);
+            // for when we draw text
+            mPaint.setTextSize(40);
+            mPaint.setTextAlign(Paint.Align.CENTER);
+            mFontMetrics = mPaint.getFontMetrics();
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+
+            canvas.drawColor(Color.WHITE);
+
+            canvas.save();
+            canvas.translate(10, 10);
+            // translate (1 point)
+            doDraw(canvas, new float[] { 0, 0 }, new float[] { 5, 5 });
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(160, 10);
+            // rotate/uniform-scale (2 points)
+            doDraw(canvas, new float[] { 32, 32, 64, 32 },
+                           new float[] { 32, 32, 64, 48 });
+            canvas.restore();
+
+            canvas.save();
+            canvas.translate(10, 110);
+            // rotate/skew (3 points)
+            doDraw(canvas, new float[] { 0, 0, 64, 0, 0, 64 },
+                           new float[] { 0, 0, 96, 0, 24, 64 });
+            canvas.restore();
+
+            canvas.save();
+            canvas.translate(160, 110);
+            // perspective (4 points)
+            doDraw(canvas, new float[] { 0, 0, 64, 0, 64, 64, 0, 64 },
+                           new float[] { 0, 0, 96, 0, 64, 96, 0, 64 });
+            canvas.restore();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
new file mode 100644
index 0000000..d264134
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+
+public class ProxyDrawable extends Drawable {
+    
+    private Drawable mProxy;
+    private boolean mMutated;
+
+    public ProxyDrawable(Drawable target) {
+        mProxy = target;
+    }
+    
+    public Drawable getProxy() {
+        return mProxy;
+    }
+    
+    public void setProxy(Drawable proxy) {
+        if (proxy != this) {
+            mProxy = proxy;
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mProxy != null) {
+            mProxy.draw(canvas);
+        }
+    }
+    
+    @Override
+    public int getIntrinsicWidth() {
+        return mProxy != null ? mProxy.getIntrinsicWidth() : -1;
+    }
+    
+    @Override
+    public int getIntrinsicHeight() {
+        return mProxy != null ? mProxy.getIntrinsicHeight() : -1;
+    }
+    
+    @Override
+    public int getOpacity() {
+        return mProxy != null ? mProxy.getOpacity() : PixelFormat.TRANSPARENT;
+    }
+    
+    @Override
+    public void setFilterBitmap(boolean filter) {
+        if (mProxy != null) {
+            mProxy.setFilterBitmap(filter);
+        }
+    }
+    
+    @Override
+    public void setDither(boolean dither) {
+        if (mProxy != null) {
+            mProxy.setDither(dither);
+        }
+    }
+    
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        if (mProxy != null) {
+            mProxy.setColorFilter(colorFilter);
+        }
+    }
+    
+    @Override
+    public void setAlpha(int alpha) {
+        if (mProxy != null) {
+            mProxy.setAlpha(alpha);
+        }
+    }
+
+    @Override
+    public Drawable mutate() {
+        if (mProxy != null && !mMutated && super.mutate() == this) {
+            mProxy.mutate();
+            mMutated = true;
+        }
+        return this;
+    }
+}
+    
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
new file mode 100644
index 0000000..833274b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class Regions extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private final Paint mPaint = new Paint();
+        private final Rect  mRect1 = new Rect();
+        private final Rect  mRect2 = new Rect();
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            mPaint.setAntiAlias(true);
+            mPaint.setTextSize(16);
+            mPaint.setTextAlign(Paint.Align.CENTER);
+            
+            mRect1.set(10, 10, 100, 80);
+            mRect2.set(50, 50, 130, 110);
+        }
+
+        private void drawOriginalRects(Canvas canvas, int alpha) {
+            mPaint.setStyle(Paint.Style.STROKE);
+            mPaint.setColor(Color.RED);
+            mPaint.setAlpha(alpha);
+            drawCentered(canvas, mRect1, mPaint);
+            mPaint.setColor(Color.BLUE);
+            mPaint.setAlpha(alpha);
+            drawCentered(canvas, mRect2, mPaint);
+            
+            // restore style
+            mPaint.setStyle(Paint.Style.FILL);
+        }
+        
+        private void drawRgn(Canvas canvas, int color, String str, Region.Op op) {
+            if (str != null) {
+                mPaint.setColor(Color.BLACK);
+                canvas.drawText(str, 80, 24, mPaint);
+            }
+            
+            Region rgn = new Region();
+            rgn.set(mRect1);
+            rgn.op(mRect2, op);
+            
+            mPaint.setColor(color);
+            RegionIterator iter = new RegionIterator(rgn);
+            Rect r = new Rect();
+            
+            canvas.translate(0, 30);
+            mPaint.setColor(color);
+            while (iter.next(r)) {
+                canvas.drawRect(r, mPaint);
+            }
+            drawOriginalRects(canvas, 0x80);
+        }
+        
+        private static void drawCentered(Canvas c, Rect r, Paint p) {
+            float inset = p.getStrokeWidth() * 0.5f;
+            if (inset == 0) {   // catch hairlines
+                inset = 0.5f;
+            }
+            c.drawRect(r.left + inset, r.top + inset,
+                       r.right - inset, r.bottom - inset, p);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.GRAY);            
+
+            canvas.save();
+            canvas.translate(80, 5);
+            drawOriginalRects(canvas, 0xFF);
+            canvas.restore();
+            
+            mPaint.setStyle(Paint.Style.FILL);
+            
+            canvas.save();
+            canvas.translate(0, 140);
+            drawRgn(canvas, Color.RED, "Union", Region.Op.UNION);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(0, 280);
+            drawRgn(canvas, Color.BLUE, "Xor", Region.Op.XOR);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(160, 140);
+            drawRgn(canvas, Color.GREEN, "Difference", Region.Op.DIFFERENCE);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(160, 280);
+            drawRgn(canvas, Color.WHITE, "Intersect", Region.Op.INTERSECT);
+            canvas.restore();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java b/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
new file mode 100644
index 0000000..b0ff035
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+public class RoundRects extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Path    mPath;
+        private Paint   mPaint;
+        private Rect    mRect;
+        private GradientDrawable mDrawable;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+
+            mPath = new Path();
+            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mRect = new Rect(0, 0, 120, 120);
+            
+            mDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR,
+                                             new int[] { 0xFFFF0000, 0xFF00FF00,
+                                                 0xFF0000FF });
+            mDrawable.setShape(GradientDrawable.RECTANGLE);
+            mDrawable.setGradientRadius((float)(Math.sqrt(2) * 60));
+        }
+        
+        static void setCornerRadii(GradientDrawable drawable, float r0,
+                                   float r1, float r2, float r3) {
+            drawable.setCornerRadii(new float[] { r0, r0, r1, r1,
+                                                  r2, r2, r3, r3 });
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            
+            mDrawable.setBounds(mRect);
+
+            float r = 16;
+            
+            canvas.save();
+            canvas.translate(10, 10);
+            mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
+            setCornerRadii(mDrawable, r, r, 0, 0);
+            mDrawable.draw(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(10 + mRect.width() + 10, 10);
+            mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
+            setCornerRadii(mDrawable, 0, 0, r, r);
+            mDrawable.draw(canvas);
+            canvas.restore();
+            
+            canvas.translate(0, mRect.height() + 10);
+    
+            canvas.save();
+            canvas.translate(10, 10);
+            mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
+            setCornerRadii(mDrawable, 0, r, r, 0);
+            mDrawable.draw(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(10 + mRect.width() + 10, 10);
+            mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
+            setCornerRadii(mDrawable, r, 0, 0, r);
+            mDrawable.draw(canvas);
+            canvas.restore();
+            
+            canvas.translate(0, mRect.height() + 10);
+            
+            canvas.save();
+            canvas.translate(10, 10);
+            mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
+            setCornerRadii(mDrawable, r, 0, r, 0);
+            mDrawable.draw(canvas);
+            canvas.restore();
+            
+            canvas.save();
+            canvas.translate(10 + mRect.width() + 10, 10);
+            mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
+            setCornerRadii(mDrawable, 0, r, 0, r);
+            mDrawable.draw(canvas);
+            canvas.restore();
+            
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
new file mode 100644
index 0000000..f55e55b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class ScaleToFit extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private final Paint   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private final Paint   mHairPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private final Paint   mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private final Matrix  mMatrix = new Matrix();
+        private final RectF   mSrcR = new RectF();
+        
+        private static final Matrix.ScaleToFit[] sFits =
+                new Matrix.ScaleToFit[] {
+            Matrix.ScaleToFit.FILL,
+            Matrix.ScaleToFit.START,
+            Matrix.ScaleToFit.CENTER,
+            Matrix.ScaleToFit.END
+        };
+        
+        private static final String[] sFitLabels = new String[] {
+            "FILL", "START", "CENTER", "END"
+        };
+        
+        private static final int[] sSrcData = new int[] {
+            80, 40, Color.RED,
+            40, 80, Color.GREEN,
+            30, 30, Color.BLUE,
+            80, 80, Color.BLACK
+        };
+        private static final int N = 4;
+        
+        private static final int WIDTH = 52;
+        private static final int HEIGHT = 52;
+        private final RectF mDstR = new RectF(0, 0, WIDTH, HEIGHT);
+
+        public SampleView(Context context) {
+            super(context);
+
+            mHairPaint.setStyle(Paint.Style.STROKE);
+            mLabelPaint.setTextSize(16);
+        }
+        
+        private void setSrcR(int index) {
+            int w = sSrcData[index*3 + 0];
+            int h = sSrcData[index*3 + 1];
+            mSrcR.set(0, 0, w, h);
+        }
+        
+        private void drawSrcR(Canvas canvas, int index) {
+            mPaint.setColor(sSrcData[index*3 + 2]);
+            canvas.drawOval(mSrcR, mPaint);
+        }
+        
+        private void drawFit(Canvas canvas, int index, Matrix.ScaleToFit stf) {
+            canvas.save();
+            
+            setSrcR(index);
+            mMatrix.setRectToRect(mSrcR, mDstR, stf);
+            canvas.concat(mMatrix);
+            drawSrcR(canvas, index);
+            
+            canvas.restore();
+            
+            canvas.drawRect(mDstR, mHairPaint);
+        }
+
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+
+            canvas.drawColor(Color.WHITE);
+
+            canvas.translate(10, 10);
+
+            canvas.save();
+            for (int i = 0; i < N; i++) {
+                setSrcR(i);
+                drawSrcR(canvas, i);
+                canvas.translate(mSrcR.width() + 15, 0);
+            }
+            canvas.restore();
+            
+            canvas.translate(0, 100);
+            for (int j = 0; j < sFits.length; j++) {
+                canvas.save();
+                for (int i = 0; i < N; i++) {
+                    drawFit(canvas, i, sFits[j]);
+                    canvas.translate(mDstR.width() + 8, 0);
+                }
+                canvas.drawText(sFitLabels[j], 0, HEIGHT*2/3, mLabelPaint);
+                canvas.restore();
+                canvas.translate(0, 80);
+            }
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java b/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
new file mode 100644
index 0000000..ed5b5ae
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.hardware.SensorListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Config;
+import android.util.Log;
+import android.view.View;
+
+public class SensorTest extends GraphicsActivity {
+
+	private SensorManager mSensorManager;
+    private SampleView mView;
+    private float[] mValues;
+    
+    private static class RunAve {
+        private final float[] mWeights;
+        private final float mWeightScale;
+        private final float[] mSamples;
+        private final int mDepth;
+        private int mCurr;
+
+        public RunAve(float[] weights) {
+            mWeights = weights;
+            
+            float sum = 0;
+            for (int i = 0; i < weights.length; i++) {
+                sum += weights[i];
+            }
+            mWeightScale = 1 / sum;
+
+            mDepth = weights.length;
+            mSamples = new float[mDepth];
+            mCurr = 0;
+        }
+        
+        public void addSample(float value) {
+            mSamples[mCurr] = value;
+            mCurr = (mCurr + 1) % mDepth;
+        }
+        
+        public float computeAve() {
+            final int depth = mDepth;
+            int index = mCurr;
+            float sum = 0;
+            for (int i = 0; i < depth; i++) {
+                sum += mWeights[i] * mSamples[index];
+                index -= 1;
+                if (index < 0) {
+                    index = depth - 1;
+                }
+            }
+            return sum * mWeightScale;
+        }
+    };
+
+    private final SensorListener mListener = new SensorListener() {
+
+        private final float[] mScale = new float[] { 2, 2.5f, 0.5f };   // accel
+
+        private float[] mPrev = new float[3];
+            
+        public void onSensorChanged(int sensor, float[] values) {
+            boolean show = false;
+            float[] diff = new float[3];
+
+            for (int i = 0; i < 3; i++) {
+                diff[i] = Math.round(mScale[i] * (values[i] - mPrev[i]) * 0.45f);
+                if (Math.abs(diff[i]) > 0) {
+                    show = true;
+                }
+                mPrev[i] = values[i];
+            }
+            
+            if (show) {
+                // only shows if we think the delta is big enough, in an attempt
+                // to detect "serious" moves left/right or up/down
+                android.util.Log.e("test", "sensorChanged " + sensor + " (" + values[0] + ", " + values[1] + ", " + values[2] + ")"
+                                   + " diff(" + diff[0] + " " + diff[1] + " " + diff[2] + ")");
+            }
+            
+            long now = android.os.SystemClock.uptimeMillis();
+            if (now - mLastGestureTime > 1000) {
+                mLastGestureTime = 0;
+                
+                float x = diff[0];
+                float y = diff[1];
+                boolean gestX = Math.abs(x) > 3;
+                boolean gestY = Math.abs(y) > 3;
+
+                if ((gestX || gestY) && !(gestX && gestY)) {
+                    if (gestX) {
+                        if (x < 0) {
+                            android.util.Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<");
+                        } else {
+                            android.util.Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>");
+                        }
+                    } else {
+                        if (y < -2) {
+                            android.util.Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<");
+                        } else {
+                            android.util.Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>");
+                        }
+                    }
+                    mLastGestureTime = now;
+                }
+            }
+        }
+        
+        private long mLastGestureTime;
+
+        public void onAccuracyChanged(int sensor, int accuracy) {
+            // TODO Auto-generated method stub
+            
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
+        mView = new SampleView(this);
+        setContentView(mView);
+//        android.util.Log.d("skia", "create " + mSensorManager);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        int mask = 0;
+//        mask |= SensorManager.SENSOR_ORIENTATION;
+        mask |= SensorManager.SENSOR_ACCELEROMETER;
+        
+        mSensorManager.registerListener(mListener, mask, SensorManager.SENSOR_DELAY_FASTEST);
+//        android.util.Log.d("skia", "resume " + mSensorManager);
+    }
+    
+    @Override
+    protected void onStop() {
+        mSensorManager.unregisterListener(mListener);
+        super.onStop();
+//        android.util.Log.d("skia", "stop " + mSensorManager);
+    }
+
+    private class SampleView extends View {
+        private Paint   mPaint = new Paint();
+        private Path    mPath = new Path();
+        private boolean mAnimate;
+        private long    mNextTime;
+
+        public SampleView(Context context) {
+            super(context);
+
+            // Construct a wedge-shaped path
+            mPath.moveTo(0, -50);
+            mPath.lineTo(-20, 60);
+            mPath.lineTo(0, 50);
+            mPath.lineTo(20, 60);
+            mPath.close();
+        }
+    
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+
+            canvas.drawColor(Color.WHITE);
+            
+            paint.setAntiAlias(true);
+            paint.setColor(Color.BLACK);
+            paint.setStyle(Paint.Style.FILL);
+
+            int w = canvas.getWidth();
+            int h = canvas.getHeight();
+            int cx = w / 2;
+            int cy = h / 2;
+
+            canvas.translate(cx, cy);
+            if (mValues != null) {            
+                canvas.rotate(-mValues[0]);
+            }
+            canvas.drawPath(mPath, mPaint);
+        }
+    
+        @Override
+        protected void onAttachedToWindow() {
+            mAnimate = true;
+            super.onAttachedToWindow();
+        }
+        
+        @Override
+        protected void onDetachedFromWindow() {
+            mAnimate = false;
+            super.onDetachedFromWindow();
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
new file mode 100644
index 0000000..6d450bb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+public class ShapeDrawable1 extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private ShapeDrawable[] mDrawables;
+        
+        private static Shader makeSweep() {
+            return new SweepGradient(150, 25,
+                new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 },
+                null);
+        }
+        
+        private static Shader makeLinear() {
+            return new LinearGradient(0, 0, 50, 50,
+                              new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF },
+                              null, Shader.TileMode.MIRROR);
+        }
+        
+        private static Shader makeTiling() {
+            int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0};
+            Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
+                                            Bitmap.Config.ARGB_8888);
+            
+            return new BitmapShader(bm, Shader.TileMode.REPEAT,
+                                        Shader.TileMode.REPEAT);
+        }
+        
+        private static class MyShapeDrawable extends ShapeDrawable {
+            private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            
+            public MyShapeDrawable(Shape s) {
+                super(s);
+                mStrokePaint.setStyle(Paint.Style.STROKE);
+            }
+            
+            public Paint getStrokePaint() {
+                return mStrokePaint;
+            }
+            
+            @Override protected void onDraw(Shape s, Canvas c, Paint p) {
+                s.draw(c, p);
+                s.draw(c, mStrokePaint);
+            }
+        }
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+
+            float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
+            RectF   inset = new RectF(6, 6, 6, 6);
+            float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
+            
+            Path path = new Path();
+            path.moveTo(50, 0);
+            path.lineTo(0, 50);
+            path.lineTo(50, 100);
+            path.lineTo(100, 50);
+            path.close();
+            
+            mDrawables = new ShapeDrawable[7];
+            mDrawables[0] = new ShapeDrawable(new RectShape());
+            mDrawables[1] = new ShapeDrawable(new OvalShape());
+            mDrawables[2] = new ShapeDrawable(new RoundRectShape(outerR, null,
+                                                                 null));
+            mDrawables[3] = new ShapeDrawable(new RoundRectShape(outerR, inset,
+                                                                 null));
+            mDrawables[4] = new ShapeDrawable(new RoundRectShape(outerR, inset,
+                                                                 innerR));
+            mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
+            mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
+            
+            mDrawables[0].getPaint().setColor(0xFFFF0000);
+            mDrawables[1].getPaint().setColor(0xFF00FF00);
+            mDrawables[2].getPaint().setColor(0xFF0000FF);
+            mDrawables[3].getPaint().setShader(makeSweep());
+            mDrawables[4].getPaint().setShader(makeLinear());
+            mDrawables[5].getPaint().setShader(makeTiling());
+            mDrawables[6].getPaint().setColor(0x88FF8844);
+            
+            PathEffect pe = new DiscretePathEffect(10, 4);
+            PathEffect pe2 = new CornerPathEffect(4);
+            mDrawables[3].getPaint().setPathEffect(
+                                                new ComposePathEffect(pe2, pe));
+        
+            MyShapeDrawable msd = (MyShapeDrawable)mDrawables[6];
+            msd.getStrokePaint().setStrokeWidth(4);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            
+            int x = 10;
+            int y = 10;
+            int width = 300;
+            int height = 50;
+            
+            for (Drawable dr : mDrawables) {
+                dr.setBounds(x, y, x + width, y + height);
+                dr.draw(canvas);                
+                y += height + 5;
+            }
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/SurfaceViewOverlay.java b/samples/ApiDemos/src/com/example/android/apis/graphics/SurfaceViewOverlay.java
new file mode 100644
index 0000000..45e5d60
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/SurfaceViewOverlay.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+import com.example.android.apis.R;
+
+/**
+ * Demonstration of overlays placed on top of a SurfaceView.
+ */
+public class SurfaceViewOverlay extends Activity {
+    View mVictimContainer;
+    View mVictim1;
+    View mVictim2;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.surface_view_overlay);
+
+        GLSurfaceView glSurfaceView =
+            (GLSurfaceView) findViewById(R.id.glsurfaceview);
+        glSurfaceView.setRenderer(new CubeRenderer(false));
+
+        // Find the views whose visibility will change
+        mVictimContainer = findViewById(R.id.hidecontainer);
+        mVictim1 = findViewById(R.id.hideme1);
+        mVictim1.setOnClickListener(new HideMeListener(mVictim1));
+        mVictim2 = findViewById(R.id.hideme2);
+        mVictim2.setOnClickListener(new HideMeListener(mVictim2));
+
+        // Find our buttons
+        Button visibleButton = (Button) findViewById(R.id.vis);
+        Button invisibleButton = (Button) findViewById(R.id.invis);
+        Button goneButton = (Button) findViewById(R.id.gone);
+
+        // Wire each button to a click listener
+        visibleButton.setOnClickListener(mVisibleListener);
+        invisibleButton.setOnClickListener(mInvisibleListener);
+        goneButton.setOnClickListener(mGoneListener);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+    }
+
+    class HideMeListener implements OnClickListener {
+        final View mTarget;
+
+        HideMeListener(View target) {
+            mTarget = target;
+        }
+
+        public void onClick(View v) {
+            mTarget.setVisibility(View.INVISIBLE);
+        }
+
+    }
+
+    OnClickListener mVisibleListener = new OnClickListener() {
+        public void onClick(View v) {
+            mVictim1.setVisibility(View.VISIBLE);
+            mVictim2.setVisibility(View.VISIBLE);
+            mVictimContainer.setVisibility(View.VISIBLE);
+        }
+    };
+
+    OnClickListener mInvisibleListener = new OnClickListener() {
+        public void onClick(View v) {
+            mVictim1.setVisibility(View.INVISIBLE);
+            mVictim2.setVisibility(View.INVISIBLE);
+            mVictimContainer.setVisibility(View.INVISIBLE);
+        }
+    };
+
+    OnClickListener mGoneListener = new OnClickListener() {
+        public void onClick(View v) {
+            mVictim1.setVisibility(View.GONE);
+            mVictim2.setVisibility(View.GONE);
+            mVictimContainer.setVisibility(View.GONE);
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
new file mode 100644
index 0000000..dc127fd
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+//import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+
+public class Sweep extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private float mRotate;
+        private Matrix mMatrix = new Matrix();
+        private Shader mShader;
+        private boolean mDoTiming;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+
+            float x = 160;
+            float y = 100;
+            mShader = new SweepGradient(x, y, new int[] { Color.GREEN,
+                                                  Color.RED,
+                                                  Color.BLUE,
+                                                  Color.GREEN }, null);
+            mPaint.setShader(mShader);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            Paint paint = mPaint;
+            float x = 160;
+            float y = 100;
+
+            canvas.drawColor(Color.WHITE);
+
+            mMatrix.setRotate(mRotate, x, y);
+            mShader.setLocalMatrix(mMatrix);
+            mRotate += 3;
+            if (mRotate >= 360) {
+                mRotate = 0;
+            }
+            invalidate();
+
+            if (mDoTiming) {
+                long now = System.currentTimeMillis();
+                for (int i = 0; i < 20; i++) {
+                    canvas.drawCircle(x, y, 80, paint);
+                }
+                now = System.currentTimeMillis() - now;
+                android.util.Log.d("skia", "sweep ms = " + (now/20.));
+            }
+            else {
+                canvas.drawCircle(x, y, 80, paint);
+            }
+        }
+
+        @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_D:
+                    mPaint.setDither(!mPaint.isDither());
+                    invalidate();
+                    return true;
+                case KeyEvent.KEYCODE_T:
+                    mDoTiming = !mDoTiming;
+                    invalidate();
+                    return true;
+            }
+            return super.onKeyDown(keyCode, event);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
new file mode 100644
index 0000000..0576a7c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+public class TextAlign extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint   mPaint;
+        private float   mX;
+        private float[] mPos;
+        
+        private Path    mPath;
+        private Paint   mPathPaint;
+        
+        private static final int DY = 30;
+        private static final String TEXT_L = "Left";
+        private static final String TEXT_C = "Center";
+        private static final String TEXT_R = "Right";
+        private static final String POSTEXT = "Positioned";
+        private static final String TEXTONPATH = "Along a path";
+        
+        private static void makePath(Path p) {
+            p.moveTo(10, 0);
+            p.cubicTo(100, -50, 200, 50, 300, 0);
+        }
+        
+        private float[] buildTextPositions(String text, float y, Paint paint) {
+            float[] widths = new float[text.length()];
+            // initially get the widths for each char
+            int n = paint.getTextWidths(text, widths);
+            // now popuplate the array, interleaving spaces for the Y values
+            float[] pos = new float[n * 2];
+            float accumulatedX = 0;
+            for (int i = 0; i < n; i++) {
+                pos[i*2 + 0] = accumulatedX;
+                pos[i*2 + 1] = y;
+                accumulatedX += widths[i];
+            }
+            return pos;
+        }
+        
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setTextSize(30);
+            mPaint.setTypeface(Typeface.SERIF);
+            
+            mPos = buildTextPositions(POSTEXT, 0, mPaint);
+            
+            mPath = new Path();
+            makePath(mPath);
+
+            mPathPaint = new Paint();
+            mPathPaint.setAntiAlias(true);
+            mPathPaint.setColor(0x800000FF);
+            mPathPaint.setStyle(Paint.Style.STROKE);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+
+            Paint p = mPaint;
+            float x = mX;
+            float y = 0;
+            float[] pos = mPos;
+            
+            // draw the normal strings
+
+            p.setColor(0x80FF0000);
+            canvas.drawLine(x, y, x, y+DY*3, p);
+            p.setColor(Color.BLACK);
+            
+            canvas.translate(0, DY);
+            p.setTextAlign(Paint.Align.LEFT);
+            canvas.drawText(TEXT_L, x, y, p);
+
+            canvas.translate(0, DY);
+            p.setTextAlign(Paint.Align.CENTER);
+            canvas.drawText(TEXT_C, x, y, p);
+
+            canvas.translate(0, DY);
+            p.setTextAlign(Paint.Align.RIGHT);
+            canvas.drawText(TEXT_R, x, y, p);
+            
+            canvas.translate(100, DY*2);
+
+            // now draw the positioned strings
+    
+            p.setColor(0xBB00FF00);
+            for (int i = 0; i < pos.length/2; i++) {
+                canvas.drawLine(pos[i*2+0], pos[i*2+1]-DY,
+                                pos[i*2+0], pos[i*2+1]+DY*2, p);
+            }
+            p.setColor(Color.BLACK);
+
+            p.setTextAlign(Paint.Align.LEFT);
+            canvas.drawPosText(POSTEXT, pos, p);
+            
+            canvas.translate(0, DY);
+            p.setTextAlign(Paint.Align.CENTER);
+            canvas.drawPosText(POSTEXT, pos, p);
+            
+            canvas.translate(0, DY);
+            p.setTextAlign(Paint.Align.RIGHT);
+            canvas.drawPosText(POSTEXT, pos, p);
+            
+            // now draw the text on path
+            
+            canvas.translate(-100, DY*2);
+
+            canvas.drawPath(mPath, mPathPaint);
+            p.setTextAlign(Paint.Align.LEFT);
+            canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
+
+            canvas.translate(0, DY*1.5f);
+            canvas.drawPath(mPath, mPathPaint);
+            p.setTextAlign(Paint.Align.CENTER);
+            canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
+            
+            canvas.translate(0, DY*1.5f);
+            canvas.drawPath(mPath, mPathPaint);
+            p.setTextAlign(Paint.Align.RIGHT);
+            canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
+        }
+
+        @Override
+        protected void onSizeChanged(int w, int h, int ow, int oh) {
+            super.onSizeChanged(w, h, ow, oh);
+            mX = w * 0.5f;  // remember the center of the screen
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
new file mode 100644
index 0000000..0942852
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+
+
+/**
+ * Demonstrates the handling of touch screen and trackball events to
+ * implement a simple painting app.
+ */
+public class TouchPaint extends GraphicsActivity {
+    /** Used as a pulse to gradually fade the contents of the window. */
+    private static final int FADE_MSG = 1;
+    
+    /** Menu ID for the command to clear the window. */
+    private static final int CLEAR_ID = Menu.FIRST;
+    /** Menu ID for the command to toggle fading. */
+    private static final int FADE_ID = Menu.FIRST+1;
+    
+    /** How often to fade the contents of the window (in ms). */
+    private static final int FADE_DELAY = 100;
+    
+    /** The view responsible for drawing the window. */
+    MyView mView;
+    /** Is fading mode enabled? */
+    boolean mFading;
+    
+    @Override protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Create and attach the view that is responsible for painting.
+        mView = new MyView(this);
+        setContentView(mView);
+        mView.requestFocus();
+        
+        // Restore the fading option if we are being thawed from a
+        // previously saved state.  Note that we are not currently remembering
+        // the contents of the bitmap.
+        mFading = savedInstanceState != null ? savedInstanceState.getBoolean("fading", true) : true;
+    }
+    
+    @Override public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, CLEAR_ID, 0, "Clear");
+        menu.add(0, FADE_ID, 0, "Fade").setCheckable(true);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override public boolean onPrepareOptionsMenu(Menu menu) {
+        menu.findItem(FADE_ID).setChecked(mFading);
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case CLEAR_ID:
+                mView.clear();
+                return true;
+            case FADE_ID:
+                mFading = !mFading;
+                if (mFading) {
+                    startFading();
+                } else {
+                    stopFading();
+                }
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        // If fading mode is enabled, then as long as we are resumed we want
+        // to run pulse to fade the contents.
+        if (mFading) {
+            startFading();
+        }
+    }
+
+    @Override protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        // Save away the fading state to restore if needed later.  Note that
+        // we do not currently save the contents of the display.
+        outState.putBoolean("fading", mFading);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        // Make sure to never run the fading pulse while we are paused or
+        // stopped.
+        stopFading();
+    }
+
+    /**
+     * Start up the pulse to fade the screen, clearing any existing pulse to
+     * ensure that we don't have multiple pulses running at a time.
+     */
+    void startFading() {
+        mHandler.removeMessages(FADE_MSG);
+        mHandler.sendMessageDelayed(
+                mHandler.obtainMessage(FADE_MSG), FADE_DELAY);
+    }
+    
+    /**
+     * Stop the pulse to fade the screen.
+     */
+    void stopFading() {
+        mHandler.removeMessages(FADE_MSG);
+    }
+    
+    private Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                // Upon receiving the fade pulse, we have the view perform a
+                // fade and then enqueue a new message to pulse at the desired
+                // next time.
+                case FADE_MSG: {
+                    mView.fade();
+                    mHandler.sendMessageDelayed(
+                            mHandler.obtainMessage(FADE_MSG), FADE_DELAY);
+                    break;
+                }
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    };
+    
+    public class MyView extends View {
+        private static final int FADE_ALPHA = 0x06;
+        private static final int MAX_FADE_STEPS = 256/FADE_ALPHA + 4;
+        private Bitmap mBitmap;
+        private Canvas mCanvas;
+        private final Rect mRect = new Rect();
+        private final Paint mPaint;
+        private final Paint mFadePaint;
+        private boolean mCurDown;
+        private int mCurX;
+        private int mCurY;
+        private float mCurPressure;
+        private float mCurSize;
+        private int mCurWidth;
+        private int mFadeSteps = MAX_FADE_STEPS;
+        
+        public MyView(Context c) {
+            super(c);
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setARGB(255, 255, 255, 255);
+            mFadePaint = new Paint();
+            mFadePaint.setDither(true);
+            mFadePaint.setARGB(FADE_ALPHA, 0, 0, 0);
+        }
+
+        public void clear() {
+            if (mCanvas != null) {
+                mPaint.setARGB(0xff, 0, 0, 0);
+                mCanvas.drawPaint(mPaint);
+                invalidate();
+                mFadeSteps = MAX_FADE_STEPS;
+            }
+        }
+        
+        public void fade() {
+            if (mCanvas != null && mFadeSteps < MAX_FADE_STEPS) {
+                mCanvas.drawPaint(mFadePaint);
+                invalidate();
+                mFadeSteps++;
+            }
+        }
+        
+        @Override protected void onSizeChanged(int w, int h, int oldw,
+                int oldh) {
+            int curW = mBitmap != null ? mBitmap.getWidth() : 0;
+            int curH = mBitmap != null ? mBitmap.getHeight() : 0;
+            if (curW >= w && curH >= h) {
+                return;
+            }
+            
+            if (curW < w) curW = w;
+            if (curH < h) curH = h;
+            
+            Bitmap newBitmap = Bitmap.createBitmap(curW, curH,
+                                                   Bitmap.Config.RGB_565);
+            Canvas newCanvas = new Canvas();
+            newCanvas.setBitmap(newBitmap);
+            if (mBitmap != null) {
+                newCanvas.drawBitmap(mBitmap, 0, 0, null);
+            }
+            mBitmap = newBitmap;
+            mCanvas = newCanvas;
+            mFadeSteps = MAX_FADE_STEPS;
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            if (mBitmap != null) {
+                canvas.drawBitmap(mBitmap, 0, 0, null);
+            }
+        }
+
+        @Override public boolean onTrackballEvent(MotionEvent event) {
+            boolean oldDown = mCurDown;
+            mCurDown = true;
+            int N = event.getHistorySize();
+            int baseX = mCurX;
+            int baseY = mCurY;
+            final float scaleX = event.getXPrecision();
+            final float scaleY = event.getYPrecision();
+            for (int i=0; i<N; i++) {
+                //Log.i("TouchPaint", "Intermediate trackball #" + i
+                //        + ": x=" + event.getHistoricalX(i)
+                //        + ", y=" + event.getHistoricalY(i));
+                drawPoint(baseX+event.getHistoricalX(i)*scaleX,
+                        baseY+event.getHistoricalY(i)*scaleY,
+                        event.getHistoricalPressure(i),
+                        event.getHistoricalSize(i));
+            }
+            //Log.i("TouchPaint", "Trackball: x=" + event.getX()
+            //        + ", y=" + event.getY());
+            drawPoint(baseX+event.getX()*scaleX, baseY+event.getY()*scaleY,
+                    event.getPressure(), event.getSize());
+            mCurDown = oldDown;
+            return true;
+        }
+        
+        @Override public boolean onTouchEvent(MotionEvent event) {
+            int action = event.getAction();
+            mCurDown = action == MotionEvent.ACTION_DOWN
+                    || action == MotionEvent.ACTION_MOVE;
+            int N = event.getHistorySize();
+            for (int i=0; i<N; i++) {
+                //Log.i("TouchPaint", "Intermediate pointer #" + i);
+                drawPoint(event.getHistoricalX(i), event.getHistoricalY(i),
+                        event.getHistoricalPressure(i),
+                        event.getHistoricalSize(i));
+            }
+            drawPoint(event.getX(), event.getY(), event.getPressure(),
+                    event.getSize());
+            return true;
+        }
+        
+        private void drawPoint(float x, float y, float pressure, float size) {
+            //Log.i("TouchPaint", "Drawing: " + x + "x" + y + " p="
+            //        + pressure + " s=" + size);
+            mCurX = (int)x;
+            mCurY = (int)y;
+            mCurPressure = pressure;
+            mCurSize = size;
+            mCurWidth = (int)(mCurSize*(getWidth()/3));
+            if (mCurWidth < 1) mCurWidth = 1;
+            if (mCurDown && mBitmap != null) {
+                int pressureLevel = (int)(mCurPressure*255);
+                mPaint.setARGB(pressureLevel, 255, 255, 255);
+                mCanvas.drawCircle(mCurX, mCurY, mCurWidth, mPaint);
+                mRect.set(mCurX-mCurWidth-2, mCurY-mCurWidth-2,
+                        mCurX+mCurWidth+2, mCurY+mCurWidth+2);
+                invalidate(mRect);
+            }
+            mFadeSteps = 0;
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
new file mode 100644
index 0000000..09d3694
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+import android.view.MotionEvent;
+
+/**
+ * Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view
+ * that uses OpenGL drawing into a dedicated surface.
+ *
+ * Shows:
+ * + How to redraw in response to user input.
+ */
+public class TouchRotateActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mGLSurfaceView = new TouchSurfaceView(this);
+        setContentView(mGLSurfaceView);
+        mGLSurfaceView.requestFocus();
+        mGLSurfaceView.setFocusableInTouchMode(true);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mGLSurfaceView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mGLSurfaceView.onPause();
+    }
+
+    private GLSurfaceView mGLSurfaceView;
+}
+
+/**
+ * Implement a simple rotation control.
+ *
+ */
+class TouchSurfaceView extends GLSurfaceView {
+
+    public TouchSurfaceView(Context context) {
+        super(context);
+        mRenderer = new CubeRenderer();
+        setRenderer(mRenderer);
+        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+    }
+
+    @Override public boolean onTrackballEvent(MotionEvent e) {
+        mRenderer.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR;
+        mRenderer.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR;
+        requestRender();
+        return true;
+    }
+
+    @Override public boolean onTouchEvent(MotionEvent e) {
+        float x = e.getX();
+        float y = e.getY();
+        switch (e.getAction()) {
+        case MotionEvent.ACTION_MOVE:
+            float dx = x - mPreviousX;
+            float dy = y - mPreviousY;
+            mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR;
+            mRenderer.mAngleY += dy * TOUCH_SCALE_FACTOR;
+            requestRender();
+        }
+        mPreviousX = x;
+        mPreviousY = y;
+        return true;
+    }
+
+    /**
+     * Render a cube.
+     */
+    private class CubeRenderer implements GLSurfaceView.Renderer {
+        public CubeRenderer() {
+            mCube = new Cube();
+        }
+
+        public void onDrawFrame(GL10 gl) {
+            /*
+             * Usually, the first thing one might want to do is to clear
+             * the screen. The most efficient way of doing this is to use
+             * glClear().
+             */
+
+            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+            /*
+             * Now we're ready to draw some 3D objects
+             */
+
+            gl.glMatrixMode(GL10.GL_MODELVIEW);
+            gl.glLoadIdentity();
+            gl.glTranslatef(0, 0, -3.0f);
+            gl.glRotatef(mAngleX, 0, 1, 0);
+            gl.glRotatef(mAngleY, 1, 0, 0);
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+            mCube.draw(gl);
+        }
+
+        public int[] getConfigSpec() {
+            // We want a depth buffer, don't care about the
+            // details of the color buffer.
+            int[] configSpec = {
+                    EGL10.EGL_DEPTH_SIZE,   16,
+                    EGL10.EGL_NONE
+            };
+            return configSpec;
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+             gl.glViewport(0, 0, width, height);
+
+             /*
+              * Set our projection matrix. This doesn't have to be done
+              * each time we draw, but usually a new projection needs to
+              * be set when the viewport is resized.
+              */
+
+             float ratio = (float) width / height;
+             gl.glMatrixMode(GL10.GL_PROJECTION);
+             gl.glLoadIdentity();
+             gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            /*
+             * By default, OpenGL enables features that improve quality
+             * but reduce performance. One might want to tweak that
+             * especially on software renderer.
+             */
+            gl.glDisable(GL10.GL_DITHER);
+
+            /*
+             * Some one-time OpenGL initialization can be made here
+             * probably based on features of this particular context
+             */
+             gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                     GL10.GL_FASTEST);
+
+
+             gl.glClearColor(1,1,1,1);
+             gl.glEnable(GL10.GL_CULL_FACE);
+             gl.glShadeModel(GL10.GL_SMOOTH);
+             gl.glEnable(GL10.GL_DEPTH_TEST);
+        }
+        private Cube mCube;
+        public float mAngleX;
+        public float mAngleY;
+    }
+
+    private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
+    private final float TRACKBALL_SCALE_FACTOR = 36.0f;
+    private CubeRenderer mRenderer;
+    private float mPreviousX;
+    private float mPreviousY;
+}
+
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TranslucentGLSurfaceViewActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TranslucentGLSurfaceViewActivity.java
new file mode 100644
index 0000000..750a47b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TranslucentGLSurfaceViewActivity.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+
+/**
+ * Wrapper activity demonstrating the use of {@link GLSurfaceView} to
+ * display translucent 3D graphics.
+ */
+public class TranslucentGLSurfaceViewActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mGLSurfaceView = new GLSurfaceView(this);
+        // Tell the cube renderer that we want to render a translucent version
+        // of the cube:
+        mGLSurfaceView.setRenderer(new CubeRenderer(true));
+        // Use a surface format with an Alpha channel:
+        mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+        setContentView(mGLSurfaceView);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGLSurfaceView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGLSurfaceView.onPause();
+    }
+
+    private GLSurfaceView mGLSurfaceView;
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
new file mode 100644
index 0000000..59f3c6c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class TriangleActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mGLView = new GLSurfaceView(this);
+        mGLView.setRenderer(new TriangleRenderer(this));
+        setContentView(mGLView);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGLView.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGLView.onResume();
+    }
+
+    private GLSurfaceView mGLView;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
new file mode 100644
index 0000000..451b927
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.os.SystemClock;
+
+import com.example.android.apis.R;
+
+public class TriangleRenderer implements GLSurfaceView.Renderer{
+
+    public TriangleRenderer(Context context) {
+        mContext = context;
+        mTriangle = new Triangle();
+    }
+
+    public int[] getConfigSpec() {
+        // We don't need a depth buffer, and don't care about our
+        // color depth.
+        int[] configSpec = {
+                EGL10.EGL_DEPTH_SIZE, 0,
+                EGL10.EGL_NONE
+        };
+        return configSpec;
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                GL10.GL_FASTEST);
+
+        gl.glClearColor(.5f, .5f, .5f, 1);
+        gl.glShadeModel(GL10.GL_SMOOTH);
+        gl.glEnable(GL10.GL_DEPTH_TEST);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+
+        /*
+         * Create our texture. This has to be done each time the
+         * surface is created.
+         */
+
+        int[] textures = new int[1];
+        gl.glGenTextures(1, textures, 0);
+
+        mTextureID = textures[0];
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+                GL10.GL_NEAREST);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
+                GL10.GL_TEXTURE_MAG_FILTER,
+                GL10.GL_LINEAR);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                GL10.GL_CLAMP_TO_EDGE);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                GL10.GL_CLAMP_TO_EDGE);
+
+        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                GL10.GL_REPLACE);
+
+        InputStream is = mContext.getResources()
+                .openRawResource(R.drawable.robot);
+        Bitmap bitmap;
+        try {
+            bitmap = BitmapFactory.decodeStream(is);
+        } finally {
+            try {
+                is.close();
+            } catch(IOException e) {
+                // Ignore.
+            }
+        }
+
+        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
+        bitmap.recycle();
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                GL10.GL_MODULATE);
+
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+
+        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+        gl.glActiveTexture(GL10.GL_TEXTURE0);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                GL10.GL_REPEAT);
+        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                GL10.GL_REPEAT);
+
+        long time = SystemClock.uptimeMillis() % 4000L;
+        float angle = 0.090f * ((int) time);
+
+        gl.glRotatef(angle, 0, 0, 1.0f);
+
+        mTriangle.draw(gl);
+    }
+
+    public void onSurfaceChanged(GL10 gl, int w, int h) {
+        gl.glViewport(0, 0, w, h);
+
+        /*
+        * Set our projection matrix. This doesn't have to be done
+        * each time we draw, but usually a new projection needs to
+        * be set when the viewport is resized.
+        */
+
+        float ratio = (float) w / h;
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+        gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
+
+    }
+
+    private Context mContext;
+    private Triangle mTriangle;
+    private int mTextureID;
+}
+
+class Triangle {
+    public Triangle() {
+
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct, i.e., they must be placed on the
+        // native heap where the garbage collector cannot
+        // move them.
+        //
+        // Buffers with multi-byte datatypes (e.g., short, int, float)
+        // must have their byte order set to native order
+
+        ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4);
+        vbb.order(ByteOrder.nativeOrder());
+        mFVertexBuffer = vbb.asFloatBuffer();
+
+        ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
+        tbb.order(ByteOrder.nativeOrder());
+        mTexBuffer = tbb.asFloatBuffer();
+
+        ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
+        ibb.order(ByteOrder.nativeOrder());
+        mIndexBuffer = ibb.asShortBuffer();
+
+        // A unit-sided equalateral triangle centered on the origin.
+        float[] coords = {
+                // X, Y, Z
+                -0.5f, -0.25f, 0,
+                 0.5f, -0.25f, 0,
+                 0.0f,  0.559016994f, 0
+        };
+
+        for (int i = 0; i < VERTS; i++) {
+            for(int j = 0; j < 3; j++) {
+                mFVertexBuffer.put(coords[i*3+j] * 2.0f);
+            }
+        }
+
+        for (int i = 0; i < VERTS; i++) {
+            for(int j = 0; j < 2; j++) {
+                mTexBuffer.put(coords[i*3+j] * 2.0f + 0.5f);
+            }
+        }
+
+        for(int i = 0; i < VERTS; i++) {
+            mIndexBuffer.put((short) i);
+        }
+
+        mFVertexBuffer.position(0);
+        mTexBuffer.position(0);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl) {
+        gl.glFrontFace(GL10.GL_CCW);
+        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
+        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, VERTS,
+                GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
+    }
+
+    private final static int VERTS = 3;
+
+    private FloatBuffer mFVertexBuffer;
+    private FloatBuffer mTexBuffer;
+    private ShortBuffer mIndexBuffer;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
new file mode 100644
index 0000000..aefc311
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.View;
+
+public class Typefaces extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private Typeface mFace;
+        
+        public SampleView(Context context) {
+            super(context);
+
+            mFace = Typeface.createFromAsset(getContext().getAssets(),
+                                             "fonts/samplefont.ttf");
+            
+            mPaint.setTextSize(64);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+
+            mPaint.setTypeface(null);
+            canvas.drawText("Default", 10, 100, mPaint);
+            mPaint.setTypeface(mFace);
+            canvas.drawText("Custom", 10, 200, mPaint);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java b/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
new file mode 100644
index 0000000..7ee99d0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.Window;
+
+public class UnicodeChart extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private Paint mBigCharPaint;
+        private Paint mLabelPaint;
+        private final char[] mChars = new char[256];
+        private final float[] mPos = new float[512];
+        
+        private int mBase;
+        
+        private static final int XMUL = 20;
+        private static final int YMUL = 28;
+        private static final int YBASE = 18;
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+            
+            mBigCharPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mBigCharPaint.setTextSize(15);
+            mBigCharPaint.setTextAlign(Paint.Align.CENTER);
+            
+            mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mLabelPaint.setTextSize(8);
+            mLabelPaint.setTextAlign(Paint.Align.CENTER);
+            
+            // the position array is the same for all charts
+            float[] pos = mPos;
+            int index = 0;
+            for (int col = 0; col < 16; col++) {
+                final float x = col * 20 + 10;
+                for (int row = 0; row < 16; row++) {
+                    pos[index++] = x;
+                    pos[index++] = row * YMUL + YBASE;
+                }
+            }
+        }
+        
+        private float computeX(int index) {
+            return (index >> 4) * 20 + 10;
+        }
+
+        private float computeY(int index) {
+            return (index & 0xF) * YMUL + YMUL;
+        }
+        
+        private void drawChart(Canvas canvas, int base) {
+            char[] chars = mChars;
+            for (int i = 0; i < 256; i++) {
+                int unichar = base + i;
+                chars[i] = (char)unichar;
+                
+                canvas.drawText(Integer.toHexString(unichar),
+                                computeX(i), computeY(i), mLabelPaint);
+            }
+            canvas.drawPosText(chars, 0, 256, mPos, mBigCharPaint);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);            
+
+            canvas.translate(0, 1);
+            drawChart(canvas, mBase * 256);
+        }
+
+        @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                    if (mBase > 0) {
+                        mBase -= 1;
+                        invalidate();
+                    }
+                    return true;
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                    mBase += 1;
+                    invalidate();
+                    return true;
+                default:
+                    break;
+            }
+            return super.onKeyDown(keyCode, event);
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
new file mode 100644
index 0000000..1e61906
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 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.graphics;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.drawable.*;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class Vertices extends GraphicsActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private final Paint mPaint = new Paint();
+        private final float[] mVerts = new float[10];
+        private final float[] mTexs = new float[10];
+        private final int[] mColors = new int[10];
+        private final short[] mIndices = { 0, 1, 2, 3, 4, 1 };
+        
+        private final Matrix mMatrix = new Matrix();
+        private final Matrix mInverse = new Matrix();
+
+        private static void setXY(float[] array, int index, float x, float y) {
+            array[index*2 + 0] = x;
+            array[index*2 + 1] = y;
+        }
+
+        public SampleView(Context context) {
+            super(context);
+            setFocusable(true);
+
+            Bitmap bm = BitmapFactory.decodeResource(getResources(),
+                                                     R.drawable.beach);
+            Shader s = new BitmapShader(bm, Shader.TileMode.CLAMP,
+                                        Shader.TileMode.CLAMP);
+            mPaint.setShader(s);
+            
+            float w = bm.getWidth();
+            float h = bm.getHeight();
+            // construct our mesh
+            setXY(mTexs, 0, w/2, h/2);
+            setXY(mTexs, 1, 0, 0);
+            setXY(mTexs, 2, w, 0);
+            setXY(mTexs, 3, w, h);
+            setXY(mTexs, 4, 0, h);
+            
+            setXY(mVerts, 0, w/2, h/2);
+            setXY(mVerts, 1, 0, 0);
+            setXY(mVerts, 2, w, 0);
+            setXY(mVerts, 3, w, h);
+            setXY(mVerts, 4, 0, h);
+            
+            mMatrix.setScale(0.8f, 0.8f);
+            mMatrix.preTranslate(20, 20);
+            mMatrix.invert(mInverse);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(0xFFCCCCCC);
+            canvas.save();
+            canvas.concat(mMatrix);
+
+            canvas.drawVertices(Canvas.VertexMode.TRIANGLE_FAN, 10, mVerts, 0,
+                                mTexs, 0, null, 0, null, 0, 0, mPaint);
+
+            canvas.translate(0, 240);
+            canvas.drawVertices(Canvas.VertexMode.TRIANGLE_FAN, 10, mVerts, 0,
+                                mTexs, 0, null, 0, mIndices, 0, 6, mPaint);
+
+            canvas.restore();
+        }
+
+        @Override public boolean onTouchEvent(MotionEvent event) {
+            float[] pt = { event.getX(), event.getY() };
+            mInverse.mapPoints(pt);
+            setXY(mVerts, 0, pt[0], pt[1]);
+            invalidate();
+            return true;
+        }
+        
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
new file mode 100644
index 0000000..b9f8424
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.Xfermode;
+import android.os.Bundle;
+import android.view.View;
+
+public class Xfermodes extends GraphicsActivity {
+    
+    // create a bitmap with a circle, used for the "dst" image
+    static Bitmap makeDst(int w, int h) {
+        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas(bm);
+        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+        
+        p.setColor(0xFFFFCC44);    
+        c.drawOval(new RectF(0, 0, w*3/4, h*3/4), p);
+        return bm;
+    }
+    
+    // create a bitmap with a rect, used for the "src" image
+    static Bitmap makeSrc(int w, int h) {
+        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas(bm);
+        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+        
+        p.setColor(0xFF66AAFF);
+        c.drawRect(w/3, h/3, w*19/20, h*19/20, p);
+        return bm;
+    }
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new SampleView(this));
+    }
+    
+    private static class SampleView extends View {
+        private static final int W = 64;
+        private static final int H = 64;
+        private static final int ROW_MAX = 4;   // number of samples per row
+
+        private Bitmap mSrcB;
+        private Bitmap mDstB;
+        private Shader mBG;     // background checker-board pattern
+        
+        private static final Xfermode[] sModes = {
+            new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
+            new PorterDuffXfermode(PorterDuff.Mode.SRC),
+            new PorterDuffXfermode(PorterDuff.Mode.DST),
+            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
+            new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
+            new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
+            new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
+            new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
+            new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
+            new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
+            new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
+            new PorterDuffXfermode(PorterDuff.Mode.XOR),
+            new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
+            new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
+            new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
+            new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
+        };
+        
+        private static final String[] sLabels = {
+            "Clear", "Src", "Dst", "SrcOver",
+            "DstOver", "SrcIn", "DstIn", "SrcOut",
+            "DstOut", "SrcATop", "DstATop", "Xor",
+            "Darken", "Lighten", "Multiply", "Screen"
+        };
+        
+        public SampleView(Context context) {
+            super(context);
+            
+            mSrcB = makeSrc(W, H);
+            mDstB = makeDst(W, H);
+            
+            // make a ckeckerboard pattern
+            Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC,
+                                            0xFFCCCCCC, 0xFFFFFFFF }, 2, 2,
+                                            Bitmap.Config.RGB_565);
+            mBG = new BitmapShader(bm,
+                                   Shader.TileMode.REPEAT,
+                                   Shader.TileMode.REPEAT);
+            Matrix m = new Matrix();
+            m.setScale(6, 6);
+            mBG.setLocalMatrix(m);
+        }
+        
+        @Override protected void onDraw(Canvas canvas) {
+            canvas.drawColor(Color.WHITE);
+            
+            Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);
+            labelP.setTextAlign(Paint.Align.CENTER);
+            
+            Paint paint = new Paint();
+            paint.setFilterBitmap(false);
+            
+            canvas.translate(15, 35);
+            
+            int x = 0;
+            int y = 0;
+            for (int i = 0; i < sModes.length; i++) {
+                // draw the border
+                paint.setStyle(Paint.Style.STROKE);
+                paint.setShader(null);
+                canvas.drawRect(x - 0.5f, y - 0.5f,
+                                x + W + 0.5f, y + H + 0.5f, paint);
+                
+                // draw the checker-board pattern
+                paint.setStyle(Paint.Style.FILL);
+                paint.setShader(mBG);
+                canvas.drawRect(x, y, x + W, y + H, paint);
+                
+                // draw the src/dst example into our offscreen bitmap
+                int sc = canvas.saveLayer(x, y, x + W, y + H, null,
+                                          Canvas.MATRIX_SAVE_FLAG |
+                                          Canvas.CLIP_SAVE_FLAG |
+                                          Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
+                                          Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
+                                          Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+                canvas.translate(x, y);
+                canvas.drawBitmap(mDstB, 0, 0, paint);
+                paint.setXfermode(sModes[i]);
+                canvas.drawBitmap(mSrcB, 0, 0, paint);
+                paint.setXfermode(null);
+                canvas.restoreToCount(sc);
+                
+                // draw the label
+                canvas.drawText(sLabels[i],
+                                x + W/2, y - labelP.getTextSize()/2, labelP);
+                
+                x += W + 10;
+                
+                // wrap around when we've drawn enough for one row
+                if ((i % ROW_MAX) == ROW_MAX - 1) {
+                    x = 0;
+                    y += H + 30;
+                }
+            }
+        }
+    }
+}
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/_index.html b/samples/ApiDemos/src/com/example/android/apis/graphics/_index.html
new file mode 100644
index 0000000..cd2ea53
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/_index.html
@@ -0,0 +1,48 @@
+
+<h3>Drawable</h3>
+<dl>
+  <dt><a href="ShapeDrawable1.html">ShapeDrawable</a></dt>
+  <dd>Demonstrates creating Drawables in XML.</dd>
+</dl>
+
+<h3>OpenGL|ES</h3>
+<dl>
+  <dt><a href="CameraPreview.html">CameraPreview</a></dt>
+  <dd> Demonstrates capturing the image stream from the camera, drawing to a surface (extending SurfaceView) on a separate thread (extending Thread).</dd>
+
+  <dt><a href="GLSurfaceViewActivity.html">GL SurfaceView</a></dt>
+  <dd>Demonstrates how to perform OpenGL rendering in to a SurfaceView.
+  <dl>
+  <dt>Code:
+  <dd> <a href="GLSurfaceViewActivity.html">GLSurfaceViewActivity.java</a>,
+    <a href="GLSurfaceView.html">GLSurfaceView.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/hello_world.html">
+  hello_world.xml</a>
+  </dl>
+  </dd>
+
+  <dt><a href="PolyToPoly.html">PolyToPoly</a></dt>
+  <dd>Demonstrates calling the <a href="@{docRoot}reference/android/graphics/Matrix.html#setPolyToPoly(float[],%20int,%20float[],%20int,%20int)">Matrix.setPolyToPoly()</a> method to translate coordinates on a canvas to a new perspective (used to simulate perspective). </dd>
+
+  <dt><a href="DrawPoints.html">DrawPoints</a></dt>
+  <dd>Demonstrates using the <a href="android.graphics.Paint">Paint</a> and <a href="android.graphics.Canvas">Canvas</a> objects to draw random points on the screen, with different colors and strokes. </dd>
+
+  <dt><a href="PathEffects.html">PathEffects</a></dt>
+  <dd> Demonstrates the use of <a href="android.graphics.Path">Path</a> and various <a href="android.graphics.PathEffect">PathEffect</a> subclasses. </dd>
+
+  <dt><a href="SurfaceViewOverlay.html">SurfaceView Overlay</a></dt>
+  <dd>Shows how you can place overlays on top of a SurfaceView.
+  <dl>
+  <dt>Code:
+  <dd> <a href="SurfaceViewOverlay.html">SurfaceViewOverlay.java</a>,
+    <a href="GLSurfaceView.html">GLSurfaceView.java</a>
+  <dt>Layout:
+  <dd> <a href="{@docRoot}samples/ApiDemos/res/layout/surface_view_overlay.html">
+  surface_view_overlay.xml</a>
+  </dl>
+  </dd>
+
+  <dt><a href="TouchPaint.html">TouchPaint</a></dt>
+  <dd> Demonstrates the handling of touch screen events to implement a simple painting app. </dd>
+</dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Cube.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Cube.java
new file mode 100644
index 0000000..015e19e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Cube.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+
+public class Cube extends GLShape {
+
+	public Cube(GLWorld world, float left, float bottom, float back, float right, float top, float front) {
+		super(world);
+       	GLVertex leftBottomBack = addVertex(left, bottom, back);
+       GLVertex rightBottomBack = addVertex(right, bottom, back);
+       	GLVertex leftTopBack = addVertex(left, top, back);
+        GLVertex rightTopBack = addVertex(right, top, back);
+       	GLVertex leftBottomFront = addVertex(left, bottom, front);
+        GLVertex rightBottomFront = addVertex(right, bottom, front);
+       	GLVertex leftTopFront = addVertex(left, top, front);
+        GLVertex rightTopFront = addVertex(right, top, front);
+
+        // vertices are added in a clockwise orientation (when viewed from the outside)
+        // bottom
+        addFace(new GLFace(leftBottomBack, leftBottomFront, rightBottomFront, rightBottomBack));
+        // front
+        addFace(new GLFace(leftBottomFront, leftTopFront, rightTopFront, rightBottomFront));
+        // left
+        addFace(new GLFace(leftBottomBack, leftTopBack, leftTopFront, leftBottomFront));
+        // right
+        addFace(new GLFace(rightBottomBack, rightBottomFront, rightTopFront, rightTopBack));
+        // back
+        addFace(new GLFace(leftBottomBack, rightBottomBack, rightTopBack, leftTopBack));
+        // top
+        addFace(new GLFace(leftTopBack, rightTopBack, rightTopFront, leftTopFront));
+		
+	}
+	
+    public static final int kBottom = 0;
+    public static final int kFront = 1;
+    public static final int kLeft = 2;
+    public static final int kRight = 3;
+    public static final int kBack = 4;
+    public static final int kTop = 5;
+
+	
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLColor.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLColor.java
new file mode 100644
index 0000000..7d4c7c1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLColor.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+public class GLColor {
+
+	public final int red;
+	public final int green;
+	public final int blue;
+	public final int alpha;
+	
+	public GLColor(int red, int green, int blue, int alpha) {
+		this.red = red;
+		this.green = green;
+		this.blue = blue;
+		this.alpha = alpha;
+	}
+
+	public GLColor(int red, int green, int blue) {
+		this.red = red;
+		this.green = green;
+		this.blue = blue;
+		this.alpha = 0x10000;
+	}
+	
+	public boolean equals(Object other) {
+		if (other instanceof GLColor) {
+			GLColor color = (GLColor)other;
+			return (red == color.red && green == color.green &&
+					blue == color.blue && alpha == color.alpha);
+		}
+		return false;
+	}
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLFace.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLFace.java
new file mode 100644
index 0000000..d6e6754
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLFace.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+import android.util.Log;
+
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+
+public class GLFace {
+
+	public GLFace() {
+		
+	}
+	
+	// for triangles
+	public GLFace(GLVertex v1, GLVertex v2, GLVertex v3) {
+		addVertex(v1);
+		addVertex(v2);
+		addVertex(v3);
+	}	
+	// for quadrilaterals
+	public GLFace(GLVertex v1, GLVertex v2, GLVertex v3, GLVertex v4) {
+		addVertex(v1);
+		addVertex(v2);
+		addVertex(v3);
+		addVertex(v4);
+	}
+		
+	public void addVertex(GLVertex v) {
+		mVertexList.add(v);
+	}
+	
+	// must be called after all vertices are added
+	public void setColor(GLColor c) {
+		
+		int last = mVertexList.size() - 1;
+		if (last < 2) {
+			Log.e("GLFace", "not enough vertices in setColor()");
+		} else {
+			GLVertex vertex = mVertexList.get(last);
+			
+			// only need to do this if the color has never been set
+			if (mColor == null) {
+				while (vertex.color != null) {
+					mVertexList.add(0, vertex);
+					mVertexList.remove(last + 1);
+					vertex = mVertexList.get(last);
+				}
+			}
+			
+			vertex.color = c;
+		}
+
+		mColor = c;
+	}
+	
+	public int getIndexCount() {
+		return (mVertexList.size() - 2) * 3;
+	}
+	
+	public void putIndices(ShortBuffer buffer) {
+		int last = mVertexList.size() - 1;
+
+		GLVertex v0 = mVertexList.get(0);
+		GLVertex vn = mVertexList.get(last);
+		
+		// push triangles into the buffer
+		for (int i = 1; i < last; i++) {
+			GLVertex v1 = mVertexList.get(i);
+			buffer.put(v0.index);
+			buffer.put(v1.index);
+			buffer.put(vn.index);
+			v0 = v1;
+		}
+	}
+	
+	private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
+	private GLColor mColor;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLShape.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLShape.java
new file mode 100644
index 0000000..2b6a824
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLShape.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class GLShape {
+
+	public GLShape(GLWorld world) {
+		mWorld = world;
+	}
+	
+	public void addFace(GLFace face) {
+		mFaceList.add(face);
+	}
+	
+	public void setFaceColor(int face, GLColor color) {
+		mFaceList.get(face).setColor(color);
+	}
+			
+	public void putIndices(ShortBuffer buffer) {
+		Iterator<GLFace> iter = mFaceList.iterator();
+		while (iter.hasNext()) {
+			GLFace face = iter.next();
+			face.putIndices(buffer);
+		}		
+	}
+	
+	public int getIndexCount() {
+		int count = 0;
+		Iterator<GLFace> iter = mFaceList.iterator();
+		while (iter.hasNext()) {
+			GLFace face = iter.next();
+			count += face.getIndexCount();
+		}		
+		return count;
+	}
+
+	public GLVertex addVertex(float x, float y, float z) {
+		
+		// look for an existing GLVertex first
+		Iterator<GLVertex> iter = mVertexList.iterator();
+		while (iter.hasNext()) {
+			GLVertex vertex = iter.next();
+			if (vertex.x == x && vertex.y == y && vertex.z == z) {
+				return vertex;
+			}
+		}
+		
+		// doesn't exist, so create new vertex
+		GLVertex vertex = mWorld.addVertex(x, y, z);
+		mVertexList.add(vertex);
+		return vertex;
+	}
+
+	public void animateTransform(M4 transform) {
+		mAnimateTransform = transform;
+		
+		if (mTransform != null)
+			transform = mTransform.multiply(transform);
+
+		Iterator<GLVertex> iter = mVertexList.iterator();
+		while (iter.hasNext()) {
+			GLVertex vertex = iter.next();
+			mWorld.transformVertex(vertex, transform);
+		}
+	}
+	
+	public void startAnimation() {
+	}
+
+	public void endAnimation() {
+		if (mTransform == null) {
+			mTransform = new M4(mAnimateTransform);
+		} else {
+			mTransform = mTransform.multiply(mAnimateTransform);
+		}
+	}
+
+	public M4						mTransform;
+	public M4						mAnimateTransform;
+	protected ArrayList<GLFace>		mFaceList = new ArrayList<GLFace>();
+	protected ArrayList<GLVertex>	mVertexList = new ArrayList<GLVertex>();
+	protected ArrayList<Integer>	mIndexList = new ArrayList<Integer>();	// make more efficient?
+	protected GLWorld mWorld;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLVertex.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLVertex.java
new file mode 100644
index 0000000..b5cd873
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLVertex.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+import java.nio.IntBuffer;
+
+public class GLVertex {
+	
+	public float x;
+	public float y;
+	public float z;
+	final short index;	// index in vertex table
+	GLColor color;
+	
+	GLVertex() {
+		this.x = 0;
+		this.y = 0;
+		this.z = 0;
+		this.index = -1;
+	}
+
+	GLVertex(float x, float y, float z, int index) {
+		this.x = x;
+		this.y = y;
+		this.z = z;
+		this.index = (short)index;
+	}
+
+	public boolean equals(Object other) {
+		if (other instanceof GLVertex) {
+			GLVertex v = (GLVertex)other;
+			return (x == v.x && y == v.y && z == v.z);
+		}
+		return false;
+	}
+
+    static public int toFixed(float x) {
+    	return (int)(x*65536.0f);
+    }
+
+	public void put(IntBuffer vertexBuffer, IntBuffer colorBuffer) {
+		vertexBuffer.put(toFixed(x));
+		vertexBuffer.put(toFixed(y));
+		vertexBuffer.put(toFixed(z));
+		if (color == null) {
+			colorBuffer.put(0);
+			colorBuffer.put(0);
+			colorBuffer.put(0);
+			colorBuffer.put(0);
+		} else {
+			colorBuffer.put(color.red);
+			colorBuffer.put(color.green);
+			colorBuffer.put(color.blue);
+			colorBuffer.put(color.alpha);
+		}
+	}
+	
+	public void update(IntBuffer vertexBuffer, M4 transform) {
+		// skip to location of vertex in mVertex buffer
+		vertexBuffer.position(index * 3);
+	
+		if (transform == null) {
+			vertexBuffer.put(toFixed(x));
+			vertexBuffer.put(toFixed(y));
+			vertexBuffer.put(toFixed(z));			
+		} else {
+			GLVertex temp = new GLVertex();
+			transform.multiply(this, temp);
+			vertexBuffer.put(toFixed(temp.x));
+			vertexBuffer.put(toFixed(temp.y));
+			vertexBuffer.put(toFixed(temp.z));
+		}
+	}
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLWorld.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLWorld.java
new file mode 100644
index 0000000..dd73174
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/GLWorld.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+import javax.microedition.khronos.opengles.GL10;
+
+public class GLWorld {
+
+	public void addShape(GLShape shape) {
+		mShapeList.add(shape);
+		mIndexCount += shape.getIndexCount();
+	}
+	
+	public void generate() {		
+	    ByteBuffer bb = ByteBuffer.allocateDirect(mVertexList.size()*4*4);
+	    bb.order(ByteOrder.nativeOrder());
+		mColorBuffer = bb.asIntBuffer();
+
+	    bb = ByteBuffer.allocateDirect(mVertexList.size()*4*3);
+	    bb.order(ByteOrder.nativeOrder());
+	    mVertexBuffer = bb.asIntBuffer();
+
+	    bb = ByteBuffer.allocateDirect(mIndexCount*2);
+	    bb.order(ByteOrder.nativeOrder());
+	    mIndexBuffer = bb.asShortBuffer();
+
+		Iterator<GLVertex> iter2 = mVertexList.iterator();
+		while (iter2.hasNext()) {
+			GLVertex vertex = iter2.next();
+			vertex.put(mVertexBuffer, mColorBuffer);
+		}
+
+		Iterator<GLShape> iter3 = mShapeList.iterator();
+		while (iter3.hasNext()) {
+			GLShape shape = iter3.next();
+			shape.putIndices(mIndexBuffer);
+		}
+	}
+	
+	public GLVertex addVertex(float x, float y, float z) {
+		GLVertex vertex = new GLVertex(x, y, z, mVertexList.size());
+		mVertexList.add(vertex);
+		return vertex;
+	}
+	
+	public void transformVertex(GLVertex vertex, M4 transform) {
+		vertex.update(mVertexBuffer, transform);
+	}
+
+	int count = 0;
+    public void draw(GL10 gl)
+    {
+		mColorBuffer.position(0);
+		mVertexBuffer.position(0);
+		mIndexBuffer.position(0);
+
+		gl.glFrontFace(GL10.GL_CW);
+        gl.glShadeModel(GL10.GL_FLAT);
+        gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
+        gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
+        gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
+        count++;
+    }
+   
+    static public float toFloat(int x) {
+    	return x/65536.0f;
+    }
+
+	private ArrayList<GLShape>	mShapeList = new ArrayList<GLShape>();	
+	private ArrayList<GLVertex>	mVertexList = new ArrayList<GLVertex>();
+	
+	private int mIndexCount = 0;
+
+    private IntBuffer   mVertexBuffer;
+    private IntBuffer   mColorBuffer;
+    private ShortBuffer mIndexBuffer;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Kube.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Kube.java
new file mode 100644
index 0000000..9332941
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Kube.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Window;
+
+import android.opengl.GLSurfaceView;
+
+import java.util.Random;
+
+public class Kube extends Activity implements KubeRenderer.AnimationCallback {
+
+    private GLWorld makeGLWorld()
+    {
+        GLWorld world = new GLWorld();
+
+        int one = 0x10000;
+        int half = 0x08000;
+        GLColor red = new GLColor(one, 0, 0);
+        GLColor green = new GLColor(0, one, 0);
+        GLColor blue = new GLColor(0, 0, one);
+        GLColor yellow = new GLColor(one, one, 0);
+        GLColor orange = new GLColor(one, half, 0);
+        GLColor white = new GLColor(one, one, one);
+        GLColor black = new GLColor(0, 0, 0);
+
+        // coordinates for our cubes
+        float c0 = -1.0f;
+        float c1 = -0.38f;
+        float c2 = -0.32f;
+        float c3 = 0.32f;
+        float c4 = 0.38f;
+        float c5 = 1.0f;
+
+        // top back, left to right
+        mCubes[0]  = new Cube(world, c0, c4, c0, c1, c5, c1);
+        mCubes[1]  = new Cube(world, c2, c4, c0, c3, c5, c1);
+        mCubes[2]  = new Cube(world, c4, c4, c0, c5, c5, c1);
+        // top middle, left to right
+        mCubes[3]  = new Cube(world, c0, c4, c2, c1, c5, c3);
+        mCubes[4]  = new Cube(world, c2, c4, c2, c3, c5, c3);
+        mCubes[5]  = new Cube(world, c4, c4, c2, c5, c5, c3);
+        // top front, left to right
+        mCubes[6]  = new Cube(world, c0, c4, c4, c1, c5, c5);
+        mCubes[7]  = new Cube(world, c2, c4, c4, c3, c5, c5);
+        mCubes[8]  = new Cube(world, c4, c4, c4, c5, c5, c5);
+        // middle back, left to right
+        mCubes[9]  = new Cube(world, c0, c2, c0, c1, c3, c1);
+        mCubes[10] = new Cube(world, c2, c2, c0, c3, c3, c1);
+        mCubes[11] = new Cube(world, c4, c2, c0, c5, c3, c1);
+        // middle middle, left to right
+        mCubes[12] = new Cube(world, c0, c2, c2, c1, c3, c3);
+        mCubes[13] = null;
+        mCubes[14] = new Cube(world, c4, c2, c2, c5, c3, c3);
+        // middle front, left to right
+        mCubes[15] = new Cube(world, c0, c2, c4, c1, c3, c5);
+        mCubes[16] = new Cube(world, c2, c2, c4, c3, c3, c5);
+        mCubes[17] = new Cube(world, c4, c2, c4, c5, c3, c5);
+        // bottom back, left to right
+        mCubes[18] = new Cube(world, c0, c0, c0, c1, c1, c1);
+        mCubes[19] = new Cube(world, c2, c0, c0, c3, c1, c1);
+        mCubes[20] = new Cube(world, c4, c0, c0, c5, c1, c1);
+        // bottom middle, left to right
+        mCubes[21] = new Cube(world, c0, c0, c2, c1, c1, c3);
+        mCubes[22] = new Cube(world, c2, c0, c2, c3, c1, c3);
+        mCubes[23] = new Cube(world, c4, c0, c2, c5, c1, c3);
+        // bottom front, left to right
+        mCubes[24] = new Cube(world, c0, c0, c4, c1, c1, c5);
+        mCubes[25] = new Cube(world, c2, c0, c4, c3, c1, c5);
+        mCubes[26] = new Cube(world, c4, c0, c4, c5, c1, c5);
+
+        // paint the sides
+        int i, j;
+        // set all faces black by default
+        for (i = 0; i < 27; i++) {
+            Cube cube = mCubes[i];
+            if (cube != null) {
+                for (j = 0; j < 6; j++)
+                    cube.setFaceColor(j, black);
+            }
+        }
+
+        // paint top
+        for (i = 0; i < 9; i++)
+            mCubes[i].setFaceColor(Cube.kTop, orange);
+        // paint bottom
+        for (i = 18; i < 27; i++)
+            mCubes[i].setFaceColor(Cube.kBottom, red);
+        // paint left
+        for (i = 0; i < 27; i += 3)
+            mCubes[i].setFaceColor(Cube.kLeft, yellow);
+        // paint right
+        for (i = 2; i < 27; i += 3)
+            mCubes[i].setFaceColor(Cube.kRight, white);
+        // paint back
+        for (i = 0; i < 27; i += 9)
+            for (j = 0; j < 3; j++)
+                mCubes[i + j].setFaceColor(Cube.kBack, blue);
+        // paint front
+        for (i = 6; i < 27; i += 9)
+            for (j = 0; j < 3; j++)
+                mCubes[i + j].setFaceColor(Cube.kFront, green);
+
+        for (i = 0; i < 27; i++)
+            if (mCubes[i] != null)
+                world.addShape(mCubes[i]);
+
+        // initialize our permutation to solved position
+        mPermutation = new int[27];
+        for (i = 0; i < mPermutation.length; i++)
+            mPermutation[i] = i;
+
+        createLayers();
+        updateLayers();
+
+        world.generate();
+
+        return world;
+    }
+
+    private void createLayers() {
+        mLayers[kUp] = new Layer(Layer.kAxisY);
+        mLayers[kDown] = new Layer(Layer.kAxisY);
+        mLayers[kLeft] = new Layer(Layer.kAxisX);
+        mLayers[kRight] = new Layer(Layer.kAxisX);
+        mLayers[kFront] = new Layer(Layer.kAxisZ);
+        mLayers[kBack] = new Layer(Layer.kAxisZ);
+        mLayers[kMiddle] = new Layer(Layer.kAxisX);
+        mLayers[kEquator] = new Layer(Layer.kAxisY);
+        mLayers[kSide] = new Layer(Layer.kAxisZ);
+    }
+
+    private void updateLayers() {
+        Layer layer;
+        GLShape[] shapes;
+        int i, j, k;
+
+        // up layer
+        layer = mLayers[kUp];
+        shapes = layer.mShapes;
+        for (i = 0; i < 9; i++)
+            shapes[i] = mCubes[mPermutation[i]];
+
+        // down layer
+        layer = mLayers[kDown];
+        shapes = layer.mShapes;
+        for (i = 18, k = 0; i < 27; i++)
+            shapes[k++] = mCubes[mPermutation[i]];
+
+        // left layer
+        layer = mLayers[kLeft];
+        shapes = layer.mShapes;
+        for (i = 0, k = 0; i < 27; i += 9)
+            for (j = 0; j < 9; j += 3)
+                shapes[k++] = mCubes[mPermutation[i + j]];
+
+        // right layer
+        layer = mLayers[kRight];
+        shapes = layer.mShapes;
+        for (i = 2, k = 0; i < 27; i += 9)
+            for (j = 0; j < 9; j += 3)
+                shapes[k++] = mCubes[mPermutation[i + j]];
+
+        // front layer
+        layer = mLayers[kFront];
+        shapes = layer.mShapes;
+        for (i = 6, k = 0; i < 27; i += 9)
+            for (j = 0; j < 3; j++)
+                shapes[k++] = mCubes[mPermutation[i + j]];
+
+        // back layer
+        layer = mLayers[kBack];
+        shapes = layer.mShapes;
+        for (i = 0, k = 0; i < 27; i += 9)
+            for (j = 0; j < 3; j++)
+                shapes[k++] = mCubes[mPermutation[i + j]];
+
+        // middle layer
+        layer = mLayers[kMiddle];
+        shapes = layer.mShapes;
+        for (i = 1, k = 0; i < 27; i += 9)
+            for (j = 0; j < 9; j += 3)
+                shapes[k++] = mCubes[mPermutation[i + j]];
+
+        // equator layer
+        layer = mLayers[kEquator];
+        shapes = layer.mShapes;
+        for (i = 9, k = 0; i < 18; i++)
+            shapes[k++] = mCubes[mPermutation[i]];
+
+        // side layer
+        layer = mLayers[kSide];
+        shapes = layer.mShapes;
+        for (i = 3, k = 0; i < 27; i += 9)
+            for (j = 0; j < 3; j++)
+                shapes[k++] = mCubes[mPermutation[i + j]];
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        // We don't need a title either.
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        mView = new GLSurfaceView(getApplication());
+        mRenderer = new KubeRenderer(makeGLWorld(), this);
+        mView.setRenderer(mRenderer);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume()
+    {
+        super.onResume();
+        mView.onResume();
+    }
+
+    @Override
+    protected void onPause()
+    {
+        super.onPause();
+        mView.onPause();
+    }
+
+    public void animate() {
+        // change our angle of view
+        mRenderer.setAngle(mRenderer.getAngle() + 1.2f);
+
+        if (mCurrentLayer == null) {
+            int layerID = mRandom.nextInt(9);
+            mCurrentLayer = mLayers[layerID];
+            mCurrentLayerPermutation = mLayerPermutations[layerID];
+            mCurrentLayer.startAnimation();
+            boolean direction = mRandom.nextBoolean();
+            int count = mRandom.nextInt(3) + 1;
+
+            count = 1;
+            direction = false;
+            mCurrentAngle = 0;
+             if (direction) {
+                mAngleIncrement = (float)Math.PI / 50;
+                   mEndAngle = mCurrentAngle + ((float)Math.PI * count) / 2f;
+               } else {
+                mAngleIncrement = -(float)Math.PI / 50;
+                   mEndAngle = mCurrentAngle - ((float)Math.PI * count) / 2f;
+            }
+        }
+
+         mCurrentAngle += mAngleIncrement;
+
+         if ((mAngleIncrement > 0f && mCurrentAngle >= mEndAngle) ||
+                 (mAngleIncrement < 0f && mCurrentAngle <= mEndAngle)) {
+             mCurrentLayer.setAngle(mEndAngle);
+             mCurrentLayer.endAnimation();
+             mCurrentLayer = null;
+
+             // adjust mPermutation based on the completed layer rotation
+             int[] newPermutation = new int[27];
+             for (int i = 0; i < 27; i++) {
+                newPermutation[i] = mPermutation[mCurrentLayerPermutation[i]];
+ //    			newPermutation[i] = mCurrentLayerPermutation[mPermutation[i]];
+             }
+             mPermutation = newPermutation;
+             updateLayers();
+
+         } else {
+             mCurrentLayer.setAngle(mCurrentAngle);
+         }
+    }
+
+    GLSurfaceView mView;
+    KubeRenderer mRenderer;
+    Cube[] mCubes = new Cube[27];
+    // a Layer for each possible move
+    Layer[] mLayers = new Layer[9];
+    // permutations corresponding to a pi/2 rotation of each layer about its axis
+    static int[][] mLayerPermutations = {
+            // permutation for UP layer
+            { 2, 5, 8, 1, 4, 7, 0, 3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
+            // permutation for DOWN layer
+            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 23, 26, 19, 22, 25, 18, 21, 24 },
+            // permutation for LEFT layer
+            { 6, 1, 2, 15, 4, 5, 24, 7, 8, 3, 10, 11, 12, 13, 14, 21, 16, 17, 0, 19, 20, 9, 22, 23, 18, 25, 26 },
+            // permutation for RIGHT layer
+            { 0, 1, 8, 3, 4, 17, 6, 7, 26, 9, 10, 5, 12, 13, 14, 15, 16, 23, 18, 19, 2, 21, 22, 11, 24, 25, 20 },
+            // permutation for FRONT layer
+            { 0, 1, 2, 3, 4, 5, 24, 15, 6, 9, 10, 11, 12, 13, 14, 25, 16, 7, 18, 19, 20, 21, 22, 23, 26, 17, 8 },
+            // permutation for BACK layer
+            { 18, 9, 0, 3, 4, 5, 6, 7, 8, 19, 10, 1, 12, 13, 14, 15, 16, 17, 20, 11, 2, 21, 22, 23, 24, 25, 26 },
+            // permutation for MIDDLE layer
+            { 0, 7, 2, 3, 16, 5, 6, 25, 8, 9, 4, 11, 12, 13, 14, 15, 22, 17, 18, 1, 20, 21, 10, 23, 24, 19, 26 },
+            // permutation for EQUATOR layer
+            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 17, 10, 13, 16, 9, 12, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
+            // permutation for SIDE layer
+            { 0, 1, 2, 21, 12, 3, 6, 7, 8, 9, 10, 11, 22, 13, 4, 15, 16, 17, 18, 19, 20, 23, 14, 5, 24, 25, 26 }
+    };
+
+
+
+    // current permutation of starting position
+    int[] mPermutation;
+
+    // for random cube movements
+    Random mRandom = new Random(System.currentTimeMillis());
+    // currently turning layer
+    Layer mCurrentLayer = null;
+    // current and final angle for current Layer animation
+    float mCurrentAngle, mEndAngle;
+    // amount to increment angle
+    float mAngleIncrement;
+    int[] mCurrentLayerPermutation;
+
+    // names for our 9 layers (based on notation from http://www.cubefreak.net/notation.html)
+    static final int kUp = 0;
+    static final int kDown = 1;
+    static final int kLeft = 2;
+    static final int kRight = 3;
+    static final int kFront = 4;
+    static final int kBack = 5;
+    static final int kMiddle = 6;
+    static final int kEquator = 7;
+    static final int kSide = 8;
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/KubeRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/KubeRenderer.java
new file mode 100644
index 0000000..252f566
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/KubeRenderer.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+import android.opengl.GLSurfaceView;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+
+/**
+ * Example of how to use OpenGL|ES in a custom view
+ *
+ */
+class KubeRenderer implements GLSurfaceView.Renderer {
+    public interface AnimationCallback {
+        void animate();
+    }
+
+    public KubeRenderer(GLWorld world, AnimationCallback callback) {
+        mWorld = world;
+        mCallback = callback;
+    }
+
+    public void onDrawFrame(GL10 gl) {
+         if (mCallback != null) {
+             mCallback.animate();
+         }
+
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear(). However we must make sure to set the scissor
+         * correctly first. The scissor is always specified in window
+         * coordinates:
+         */
+
+        gl.glClearColor(0.5f,0.5f,0.5f,1);
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D object
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(0, 0, -3.0f);
+        gl.glScalef(0.5f, 0.5f, 0.5f);
+        gl.glRotatef(mAngle,        0, 1, 0);
+        gl.glRotatef(mAngle*0.25f,  1, 0, 0);
+
+        gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+        gl.glEnable(GL10.GL_CULL_FACE);
+        gl.glShadeModel(GL10.GL_SMOOTH);
+        gl.glEnable(GL10.GL_DEPTH_TEST);
+
+        mWorld.draw(gl);
+    }
+
+    public int[] getConfigSpec() {
+        // Need a depth buffer, don't care about color depth.
+        int[] configSpec = {
+                EGL10.EGL_DEPTH_SIZE,   16,
+                EGL10.EGL_NONE
+        };
+        return configSpec;
+    }
+
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+        gl.glViewport(0, 0, width, height);
+
+        /*
+         * Set our projection matrix. This doesn't have to be done
+         * each time we draw, but usually a new projection needs to be set
+         * when the viewport is resized.
+         */
+
+        float ratio = (float)width / height;
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+        gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
+
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+        gl.glActiveTexture(GL10.GL_TEXTURE0);
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        // Nothing special, don't have any textures we need to recreate.
+    }
+
+    public void setAngle(float angle) {
+        mAngle = angle;
+    }
+
+    public float getAngle() {
+        return mAngle;
+    }
+
+    private GLWorld mWorld;
+    private AnimationCallback mCallback;
+    private float mAngle;
+}
+
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Layer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Layer.java
new file mode 100644
index 0000000..5e27296
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/Layer.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+public class Layer {
+	
+	public Layer(int axis) {
+		// start with identity matrix for transformation
+		mAxis = axis;
+		mTransform.setIdentity();
+	}
+	
+	public void startAnimation() {
+		for (int i = 0; i < mShapes.length; i++) {
+			GLShape shape = mShapes[i];
+			if (shape != null) {
+				shape.startAnimation();
+			}	
+		}
+	}
+
+	public void endAnimation() {
+		for (int i = 0; i < mShapes.length; i++) {
+			GLShape shape = mShapes[i];
+			if (shape != null) {
+				shape.endAnimation();
+			}	
+		}
+	}
+	
+	public void setAngle(float angle) {
+		// normalize the angle
+		float twopi = (float)Math.PI *2f;
+		while (angle >= twopi) angle -= twopi;
+		while (angle < 0f) angle += twopi;
+//		mAngle = angle;
+		
+		float sin = (float)Math.sin(angle);
+		float cos = (float)Math.cos(angle);
+		
+		float[][] m = mTransform.m;
+		switch (mAxis) {
+			case kAxisX:
+				m[1][1] = cos;
+				m[1][2] = sin;
+				m[2][1] = -sin;
+				m[2][2] = cos;
+				m[0][0] = 1f;
+				m[0][1] = m[0][2] = m[1][0] = m[2][0] = 0f;
+				break;
+			case kAxisY:
+				m[0][0] = cos;
+				m[0][2] = sin;
+				m[2][0] = -sin;
+				m[2][2] = cos;
+				m[1][1] = 1f;
+				m[0][1] = m[1][0] = m[1][2] = m[2][1] = 0f;
+				break;
+			case kAxisZ:
+				m[0][0] = cos;
+				m[0][1] = sin;
+				m[1][0] = -sin;
+				m[1][1] = cos;
+				m[2][2] = 1f;
+				m[2][0] = m[2][1] = m[0][2] = m[1][2] = 0f;
+				break;
+		}
+		
+		for (int i = 0; i < mShapes.length; i++) {
+			GLShape shape = mShapes[i];
+			if (shape != null) {
+				shape.animateTransform(mTransform);
+			}
+		}
+	}
+	
+	GLShape[] mShapes = new GLShape[9];
+	M4 mTransform = new M4();
+//	float mAngle;
+
+	// which axis do we rotate around?
+	// 0 for X, 1 for Y, 2 for Z
+	int mAxis;
+	static public final int kAxisX = 0;
+	static public final int kAxisY = 1;
+	static public final int kAxisZ = 2;	
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/kube/M4.java b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/M4.java
new file mode 100644
index 0000000..b6cc2fe
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/kube/M4.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 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.graphics.kube;
+
+/** 
+ * 
+ * A 4x4 float matrix
+ *
+ */
+public class M4 {
+	public float[][] m = new float[4][4];
+	
+	public M4() {
+	}
+	
+	public M4(M4 other) {
+		for (int i = 0; i < 4; i++) {
+			for (int j = 0; j < 4; j++) {
+				m[i][j] = other.m[i][j];
+			}
+		}		
+	}
+
+	public void multiply(GLVertex src, GLVertex dest) {
+		dest.x = src.x * m[0][0] + src.y * m[1][0] + src.z * m[2][0] + m[3][0];
+		dest.y = src.x * m[0][1] + src.y * m[1][1] + src.z * m[2][1] + m[3][1];
+		dest.z = src.x * m[0][2] + src.y * m[1][2] + src.z * m[2][2] + m[3][2];
+	}
+	
+	public M4 multiply(M4 other) {
+		M4 result = new M4();
+		float[][] m1 = m;
+		float[][] m2 = other.m;
+		
+		for (int i = 0; i < 4; i++) {
+			for (int j = 0; j < 4; j++) {
+				result.m[i][j] = m1[i][0]*m2[0][j] + m1[i][1]*m2[1][j] + m1[i][2]*m2[2][j] + m1[i][3]*m2[3][j];
+			}
+		}
+		
+		return result;
+	}
+	
+	public void setIdentity() {
+		for (int i = 0; i < 4; i++) {
+			for (int j = 0; j < 4; j++) {
+				m[i][j] = (i == j ? 1f : 0f);
+			}
+		}
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder("[ ");
+		for (int i = 0; i < 4; i++) {
+			for (int j = 0; j < 4; j++) {
+				builder.append(m[i][j]);
+				builder.append(" ");
+			}
+			if (i < 2)
+				builder.append("\n  ");
+		}
+		builder.append(" ]");
+		return builder.toString();
+	}
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/Grid.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/Grid.java
new file mode 100644
index 0000000..81863a0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/Grid.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics.spritetext;
+
+import java.nio.CharBuffer;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A 2D rectangular mesh. Can be drawn textured or untextured.
+ *
+ */
+class Grid {
+
+	public Grid(int w, int h) {
+		if (w < 0 || w >= 65536) {
+			throw new IllegalArgumentException("w");
+		}
+		if (h < 0 || h >= 65536) {
+			throw new IllegalArgumentException("h");
+		}
+		if (w * h >= 65536) {
+			throw new IllegalArgumentException("w * h >= 65536");
+		}
+
+		mW = w;
+		mH = h;
+		int size = w * h;
+		mVertexArray = new float[size * 3];
+		mVertexBuffer = FloatBuffer.wrap(mVertexArray);
+
+		mTexCoordArray = new float[size * 2];
+		mTexCoordBuffer = FloatBuffer.wrap(mTexCoordArray);
+
+		int quadW = mW - 1;
+		int quadH = mH - 1;
+		int quadCount = quadW * quadH;
+		int indexCount = quadCount * 6;
+		mIndexCount = indexCount;
+		char[] indexArray = new char[indexCount];
+
+		/*
+		 * Initialize triangle list mesh.
+		 *
+		 *     [0]-----[  1] ...
+		 *      |    /   |
+		 *      |   /    |
+		 *      |  /     |
+		 *     [w]-----[w+1] ...
+		 *      |       |
+		 *
+		 */
+
+		{
+			int i = 0;
+			for (int y = 0; y < quadH; y++) {
+				for (int x = 0; x < quadW; x++) {
+					char a = (char) (y * mW + x);
+					char b = (char) (y * mW + x + 1);
+					char c = (char) ((y + 1) * mW + x);
+					char d = (char) ((y + 1) * mW + x + 1);
+
+					indexArray[i++] = a;
+					indexArray[i++] = b;
+					indexArray[i++] = c;
+
+					indexArray[i++] = b;
+					indexArray[i++] = c;
+					indexArray[i++] = d;
+				}
+			}
+		}
+
+		mIndexBuffer = CharBuffer.wrap(indexArray);
+	}
+
+	void set(int i, int j, float x, float y, float z, float u, float v) {
+		if (i < 0 || i >= mW) {
+			throw new IllegalArgumentException("i");
+		}
+		if (j < 0 || j >= mH) {
+			throw new IllegalArgumentException("j");
+		}
+
+		int index = mW * j + i;
+
+		int posIndex = index * 3;
+		mVertexArray[posIndex] = x;
+		mVertexArray[posIndex + 1] = y;
+		mVertexArray[posIndex + 2] = z;
+
+		int texIndex = index * 2;
+		mTexCoordArray[texIndex] = u;
+		mTexCoordArray[texIndex + 1] = v;
+	}
+
+	public void draw(GL10 gl, boolean useTexture) {
+		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
+
+		if (useTexture) {
+			gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+			gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexCoordBuffer);
+			gl.glEnable(GL10.GL_TEXTURE_2D);
+		} else {
+			gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+			gl.glDisable(GL10.GL_TEXTURE_2D);
+		}
+
+		gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount,
+				GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
+        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+	}
+
+	private FloatBuffer mVertexBuffer;
+	private float[] mVertexArray;
+
+	private FloatBuffer mTexCoordBuffer;
+	private float[] mTexCoordArray;
+
+	private CharBuffer mIndexBuffer;
+
+	private int mW;
+	private int mH;
+	private int mIndexCount;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/LabelMaker.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/LabelMaker.java
new file mode 100644
index 0000000..4bf87f7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/LabelMaker.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics.spritetext;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Paint.Style;
+import android.graphics.drawable.Drawable;
+import android.opengl.GLUtils;
+
+import java.util.ArrayList;
+
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+/**
+ * An OpenGL text label maker.
+ *
+ *
+ * OpenGL labels are implemented by creating a Bitmap, drawing all the labels
+ * into the Bitmap, converting the Bitmap into an Alpha texture, and creating a
+ * mesh for each label
+ *
+ * The benefits of this approach are that the labels are drawn using the high
+ * quality anti-aliased font rasterizer, full character set support, and all the
+ * text labels are stored on a single texture, which makes it faster to use.
+ *
+ * The drawbacks are that you can only have as many labels as will fit onto one
+ * texture, and you have to recreate the whole texture if any label text
+ * changes.
+ *
+ */
+public class LabelMaker {
+    /**
+     * Create a label maker
+     * or maximum compatibility with various OpenGL ES implementations,
+     * the strike width and height must be powers of two,
+     * We want the strike width to be at least as wide as the widest window.
+     *
+     * @param fullColor true if we want a full color backing store (4444),
+     * otherwise we generate a grey L8 backing store.
+     * @param strikeWidth width of strike
+     * @param strikeHeight height of strike
+     */
+    public LabelMaker(boolean fullColor, int strikeWidth, int strikeHeight) {
+        mFullColor = fullColor;
+        mStrikeWidth = strikeWidth;
+        mStrikeHeight = strikeHeight;
+        mTexelWidth = (float) (1.0 / mStrikeWidth);
+        mTexelHeight = (float) (1.0 / mStrikeHeight);
+        mClearPaint = new Paint();
+        mClearPaint.setARGB(0, 0, 0, 0);
+        mClearPaint.setStyle(Style.FILL);
+        mState = STATE_NEW;
+    }
+
+    /**
+     * Call to initialize the class.
+     * Call whenever the surface has been created.
+     *
+     * @param gl
+     */
+    public void initialize(GL10 gl) {
+        mState = STATE_INITIALIZED;
+        int[] textures = new int[1];
+        gl.glGenTextures(1, textures, 0);
+        mTextureID = textures[0];
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+
+        // Use Nearest for performance.
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+                GL10.GL_NEAREST);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
+                GL10.GL_NEAREST);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                GL10.GL_CLAMP_TO_EDGE);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                GL10.GL_CLAMP_TO_EDGE);
+
+        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                GL10.GL_REPLACE);
+    }
+
+    /**
+     * Call when the surface has been destroyed
+     */
+    public void shutdown(GL10 gl) {
+        if ( gl != null) {
+            if (mState > STATE_NEW) {
+                int[] textures = new int[1];
+                textures[0] = mTextureID;
+                gl.glDeleteTextures(1, textures, 0);
+                mState = STATE_NEW;
+            }
+        }
+    }
+
+    /**
+     * Call before adding labels. Clears out any existing labels.
+     *
+     * @param gl
+     */
+    public void beginAdding(GL10 gl) {
+        checkState(STATE_INITIALIZED, STATE_ADDING);
+        mLabels.clear();
+        mU = 0;
+        mV = 0;
+        mLineHeight = 0;
+        Bitmap.Config config = mFullColor ?
+                Bitmap.Config.ARGB_4444 : Bitmap.Config.ALPHA_8;
+        mBitmap = Bitmap.createBitmap(mStrikeWidth, mStrikeHeight, config);
+        mCanvas = new Canvas(mBitmap);
+        mBitmap.eraseColor(0);
+    }
+
+    /**
+     * Call to add a label
+     *
+     * @param gl
+     * @param text the text of the label
+     * @param textPaint the paint of the label
+     * @return the id of the label, used to measure and draw the label
+     */
+    public int add(GL10 gl, String text, Paint textPaint) {
+        return add(gl, null, text, textPaint);
+    }
+
+    /**
+     * Call to add a label
+     *
+     * @param gl
+     * @param text the text of the label
+     * @param textPaint the paint of the label
+     * @return the id of the label, used to measure and draw the label
+     */
+    public int add(GL10 gl, Drawable background, String text, Paint textPaint) {
+        return add(gl, background, text, textPaint, 0, 0);
+    }
+
+    /**
+     * Call to add a label
+     * @return the id of the label, used to measure and draw the label
+     */
+    public int add(GL10 gl, Drawable drawable, int minWidth, int minHeight) {
+        return add(gl, drawable, null, null, minWidth, minHeight);
+    }
+
+    /**
+     * Call to add a label
+     *
+     * @param gl
+     * @param text the text of the label
+     * @param textPaint the paint of the label
+     * @return the id of the label, used to measure and draw the label
+     */
+    public int add(GL10 gl, Drawable background, String text, Paint textPaint,
+            int minWidth, int minHeight) {
+        checkState(STATE_ADDING, STATE_ADDING);
+        boolean drawBackground = background != null;
+        boolean drawText = (text != null) && (textPaint != null);
+
+        Rect padding = new Rect();
+        if (drawBackground) {
+            background.getPadding(padding);
+            minWidth = Math.max(minWidth, background.getMinimumWidth());
+            minHeight = Math.max(minHeight, background.getMinimumHeight());
+        }
+
+        int ascent = 0;
+        int descent = 0;
+        int measuredTextWidth = 0;
+        if (drawText) {
+            // Paint.ascent is negative, so negate it.
+            ascent = (int) Math.ceil(-textPaint.ascent());
+            descent = (int) Math.ceil(textPaint.descent());
+            measuredTextWidth = (int) Math.ceil(textPaint.measureText(text));
+        }
+        int textHeight = ascent + descent;
+        int textWidth = Math.min(mStrikeWidth,measuredTextWidth);
+
+        int padHeight = padding.top + padding.bottom;
+        int padWidth = padding.left + padding.right;
+        int height = Math.max(minHeight, textHeight + padHeight);
+        int width = Math.max(minWidth, textWidth + padWidth);
+        int effectiveTextHeight = height - padHeight;
+        int effectiveTextWidth = width - padWidth;
+
+        int centerOffsetHeight = (effectiveTextHeight - textHeight) / 2;
+        int centerOffsetWidth = (effectiveTextWidth - textWidth) / 2;
+
+        // Make changes to the local variables, only commit them
+        // to the member variables after we've decided not to throw
+        // any exceptions.
+
+        int u = mU;
+        int v = mV;
+        int lineHeight = mLineHeight;
+
+        if (width > mStrikeWidth) {
+            width = mStrikeWidth;
+        }
+
+        // Is there room for this string on the current line?
+        if (u + width > mStrikeWidth) {
+            // No room, go to the next line:
+            u = 0;
+            v += lineHeight;
+            lineHeight = 0;
+        }
+        lineHeight = Math.max(lineHeight, height);
+        if (v + lineHeight > mStrikeHeight) {
+            throw new IllegalArgumentException("Out of texture space.");
+        }
+
+        int u2 = u + width;
+        int vBase = v + ascent;
+        int v2 = v + height;
+
+        if (drawBackground) {
+            background.setBounds(u, v, u + width, v + height);
+            background.draw(mCanvas);
+        }
+
+        if (drawText) {
+            mCanvas.drawText(text,
+                    u + padding.left + centerOffsetWidth,
+                    vBase + padding.top + centerOffsetHeight,
+                    textPaint);
+        }
+
+        Grid grid = new Grid(2, 2);
+        // Grid.set arguments: i, j, x, y, z, u, v
+
+        float texU = u * mTexelWidth;
+        float texU2 = u2 * mTexelWidth;
+        float texV = 1.0f - v * mTexelHeight;
+        float texV2 = 1.0f - v2 * mTexelHeight;
+
+        grid.set(0, 0,   0.0f,   0.0f, 0.0f, texU , texV2);
+        grid.set(1, 0,  width,   0.0f, 0.0f, texU2, texV2);
+        grid.set(0, 1,   0.0f, height, 0.0f, texU , texV );
+        grid.set(1, 1,  width, height, 0.0f, texU2, texV );
+
+        // We know there's enough space, so update the member variables
+        mU = u + width;
+        mV = v;
+        mLineHeight = lineHeight;
+        mLabels.add(new Label(grid, width, height, ascent,
+                u, v + height, width, -height));
+        return mLabels.size() - 1;
+    }
+
+    /**
+     * Call to end adding labels. Must be called before drawing starts.
+     *
+     * @param gl
+     */
+    public void endAdding(GL10 gl) {
+        checkState(STATE_ADDING, STATE_INITIALIZED);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
+        // Reclaim storage used by bitmap and canvas.
+        mBitmap.recycle();
+        mBitmap = null;
+        mCanvas = null;
+    }
+
+    /**
+     * Get the width in pixels of a given label.
+     *
+     * @param labelID
+     * @return the width in pixels
+     */
+    public float getWidth(int labelID) {
+        return mLabels.get(labelID).width;
+    }
+
+    /**
+     * Get the height in pixels of a given label.
+     *
+     * @param labelID
+     * @return the height in pixels
+     */
+    public float getHeight(int labelID) {
+        return mLabels.get(labelID).height;
+    }
+
+    /**
+     * Get the baseline of a given label. That's how many pixels from the top of
+     * the label to the text baseline. (This is equivalent to the negative of
+     * the label's paint's ascent.)
+     *
+     * @param labelID
+     * @return the baseline in pixels.
+     */
+    public float getBaseline(int labelID) {
+        return mLabels.get(labelID).baseline;
+    }
+
+    /**
+     * Begin drawing labels. Sets the OpenGL state for rapid drawing.
+     *
+     * @param gl
+     * @param viewWidth
+     * @param viewHeight
+     */
+    public void beginDrawing(GL10 gl, float viewWidth, float viewHeight) {
+        checkState(STATE_INITIALIZED, STATE_DRAWING);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        gl.glShadeModel(GL10.GL_FLAT);
+        gl.glEnable(GL10.GL_BLEND);
+        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
+        gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glPushMatrix();
+        gl.glLoadIdentity();
+        gl.glOrthof(0.0f, viewWidth, 0.0f, viewHeight, 0.0f, 1.0f);
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glPushMatrix();
+        gl.glLoadIdentity();
+        // Magic offsets to promote consistent rasterization.
+        gl.glTranslatef(0.375f, 0.375f, 0.0f);
+    }
+
+    /**
+     * Draw a given label at a given x,y position, expressed in pixels, with the
+     * lower-left-hand-corner of the view being (0,0).
+     *
+     * @param gl
+     * @param x
+     * @param y
+     * @param labelID
+     */
+    public void draw(GL10 gl, float x, float y, int labelID) {
+        checkState(STATE_DRAWING, STATE_DRAWING);
+        gl.glPushMatrix();
+        float snappedX = (float) Math.floor(x);
+        float snappedY = (float) Math.floor(y);
+        gl.glTranslatef(snappedX, snappedY, 0.0f);
+        Label label = mLabels.get(labelID);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+        ((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
+                GL11Ext.GL_TEXTURE_CROP_RECT_OES, label.mCrop, 0);
+        ((GL11Ext)gl).glDrawTexiOES((int) snappedX, (int) snappedY, 0,
+                (int) label.width, (int) label.height);
+        gl.glPopMatrix();
+    }
+
+    /**
+     * Ends the drawing and restores the OpenGL state.
+     *
+     * @param gl
+     */
+    public void endDrawing(GL10 gl) {
+        checkState(STATE_DRAWING, STATE_INITIALIZED);
+        gl.glDisable(GL10.GL_BLEND);
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glPopMatrix();
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glPopMatrix();
+    }
+
+    private void checkState(int oldState, int newState) {
+        if (mState != oldState) {
+            throw new IllegalArgumentException("Can't call this method now.");
+        }
+        mState = newState;
+    }
+
+    private static class Label {
+        public Label(Grid grid, float width, float height, float baseLine,
+                int cropU, int cropV, int cropW, int cropH) {
+            this.grid = grid;
+            this.width = width;
+            this.height = height;
+            this.baseline = baseLine;
+            int[] crop = new int[4];
+            crop[0] = cropU;
+            crop[1] = cropV;
+            crop[2] = cropW;
+            crop[3] = cropH;
+            mCrop = crop;
+        }
+
+        public Grid grid;
+        public float width;
+        public float height;
+        public float baseline;
+        public int[] mCrop;
+    }
+
+    private int mStrikeWidth;
+    private int mStrikeHeight;
+    private boolean mFullColor;
+    private Bitmap mBitmap;
+    private Canvas mCanvas;
+    private Paint mClearPaint;
+
+    private int mTextureID;
+
+    private float mTexelWidth;  // Convert texel to U
+    private float mTexelHeight; // Convert texel to V
+    private int mU;
+    private int mV;
+    private int mLineHeight;
+    private ArrayList<Label> mLabels = new ArrayList<Label>();
+
+    private static final int STATE_NEW = 0;
+    private static final int STATE_INITIALIZED = 1;
+    private static final int STATE_ADDING = 2;
+    private static final int STATE_DRAWING = 3;
+    private int mState;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixGrabber.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixGrabber.java
new file mode 100644
index 0000000..87c9076
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixGrabber.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics.spritetext;
+
+import javax.microedition.khronos.opengles.GL10;
+
+class MatrixGrabber {
+    public MatrixGrabber() {
+        mModelView = new float[16];
+        mProjection = new float[16];
+    }
+
+    /**
+     * Record the current modelView and projection matrix state.
+     * Has the side effect of setting the current matrix state to GL_MODELVIEW
+     * @param gl
+     */
+    public void getCurrentState(GL10 gl) {
+        getCurrentProjection(gl);
+        getCurrentModelView(gl);
+    }
+
+    /**
+     * Record the current modelView matrix state. Has the side effect of
+     * setting the current matrix state to GL_MODELVIEW
+     * @param gl
+     */
+    public void getCurrentModelView(GL10 gl) {
+        getMatrix(gl, GL10.GL_MODELVIEW, mModelView);
+    }
+
+    /**
+     * Record the current projection matrix state. Has the side effect of
+     * setting the current matrix state to GL_PROJECTION
+     * @param gl
+     */
+    public void getCurrentProjection(GL10 gl) {
+        getMatrix(gl, GL10.GL_PROJECTION, mProjection);
+    }
+
+    private void getMatrix(GL10 gl, int mode, float[] mat) {
+        MatrixTrackingGL gl2 = (MatrixTrackingGL) gl;
+        gl2.glMatrixMode(mode);
+        gl2.getMatrix(mat, 0);
+    }
+
+    public float[] mModelView;
+    public float[] mProjection;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixStack.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixStack.java
new file mode 100644
index 0000000..a07f614
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixStack.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics.spritetext;
+
+import android.opengl.Matrix;
+
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+/**
+ * A matrix stack, similar to OpenGL ES's internal matrix stack.
+ */
+public class MatrixStack {
+    public MatrixStack() {
+        commonInit(DEFAULT_MAX_DEPTH);
+    }
+
+    public MatrixStack(int maxDepth) {
+        commonInit(maxDepth);
+    }
+
+    private void commonInit(int maxDepth) {
+        mMatrix = new float[maxDepth * MATRIX_SIZE];
+        mTemp = new float[MATRIX_SIZE * 2];
+        glLoadIdentity();
+    }
+
+    public void glFrustumf(float left, float right, float bottom, float top,
+            float near, float far) {
+        Matrix.frustumM(mMatrix, mTop, left, right, bottom, top, near, far);
+    }
+
+    public void glFrustumx(int left, int right, int bottom, int top, int near,
+            int far) {
+        glFrustumf(fixedToFloat(left),fixedToFloat(right),
+                fixedToFloat(bottom), fixedToFloat(top),
+                fixedToFloat(near), fixedToFloat(far));
+    }
+
+    public void glLoadIdentity() {
+        Matrix.setIdentityM(mMatrix, mTop);
+    }
+
+    public void glLoadMatrixf(float[] m, int offset) {
+        System.arraycopy(m, offset, mMatrix, mTop, MATRIX_SIZE);
+    }
+
+    public void glLoadMatrixf(FloatBuffer m) {
+        m.get(mMatrix, mTop, MATRIX_SIZE);
+    }
+
+    public void glLoadMatrixx(int[] m, int offset) {
+        for(int i = 0; i < MATRIX_SIZE; i++) {
+            mMatrix[mTop + i] = fixedToFloat(m[offset + i]);
+        }
+    }
+
+    public void glLoadMatrixx(IntBuffer m) {
+        for(int i = 0; i < MATRIX_SIZE; i++) {
+            mMatrix[mTop + i] = fixedToFloat(m.get());
+        }
+    }
+
+    public void glMultMatrixf(float[] m, int offset) {
+        System.arraycopy(mMatrix, mTop, mTemp, 0, MATRIX_SIZE);
+        Matrix.multiplyMM(mMatrix, mTop, mTemp, 0, m, offset);
+    }
+
+    public void glMultMatrixf(FloatBuffer m) {
+        m.get(mTemp, MATRIX_SIZE, MATRIX_SIZE);
+        glMultMatrixf(mTemp, MATRIX_SIZE);
+    }
+
+    public void glMultMatrixx(int[] m, int offset) {
+        for(int i = 0; i < MATRIX_SIZE; i++) {
+            mTemp[MATRIX_SIZE + i] = fixedToFloat(m[offset + i]);
+        }
+        glMultMatrixf(mTemp, MATRIX_SIZE);
+    }
+
+    public void glMultMatrixx(IntBuffer m) {
+        for(int i = 0; i < MATRIX_SIZE; i++) {
+            mTemp[MATRIX_SIZE + i] = fixedToFloat(m.get());
+        }
+        glMultMatrixf(mTemp, MATRIX_SIZE);
+    }
+
+    public void glOrthof(float left, float right, float bottom, float top,
+            float near, float far) {
+        Matrix.orthoM(mMatrix, mTop, left, right, bottom, top, near, far);
+    }
+
+    public void glOrthox(int left, int right, int bottom, int top, int near,
+            int far) {
+        glOrthof(fixedToFloat(left), fixedToFloat(right),
+                fixedToFloat(bottom), fixedToFloat(top),
+                fixedToFloat(near), fixedToFloat(far));
+    }
+
+    public void glPopMatrix() {
+        preflight_adjust(-1);
+        adjust(-1);
+    }
+
+    public void glPushMatrix() {
+        preflight_adjust(1);
+        System.arraycopy(mMatrix, mTop, mMatrix, mTop + MATRIX_SIZE,
+                MATRIX_SIZE);
+        adjust(1);
+    }
+
+    public void glRotatef(float angle, float x, float y, float z) {
+        Matrix.setRotateM(mTemp, 0, angle, x, y, z);
+        System.arraycopy(mMatrix, mTop, mTemp, MATRIX_SIZE, MATRIX_SIZE);
+        Matrix.multiplyMM(mMatrix, mTop, mTemp, MATRIX_SIZE, mTemp, 0);
+    }
+
+    public void glRotatex(int angle, int x, int y, int z) {
+        glRotatef(angle, fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    }
+
+    public void glScalef(float x, float y, float z) {
+        Matrix.scaleM(mMatrix, mTop, x, y, z);
+    }
+
+    public void glScalex(int x, int y, int z) {
+        glScalef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    }
+
+    public void glTranslatef(float x, float y, float z) {
+        Matrix.translateM(mMatrix, mTop, x, y, z);
+    }
+
+    public void glTranslatex(int x, int y, int z) {
+        glTranslatef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    }
+
+    public void getMatrix(float[] dest, int offset) {
+        System.arraycopy(mMatrix, mTop, dest, offset, MATRIX_SIZE);
+    }
+
+    private float fixedToFloat(int x) {
+        return x * (1.0f / 65536.0f);
+    }
+
+    private void preflight_adjust(int dir) {
+        int newTop = mTop + dir * MATRIX_SIZE;
+        if (newTop < 0) {
+            throw new IllegalArgumentException("stack underflow");
+        }
+        if (newTop + MATRIX_SIZE > mMatrix.length) {
+            throw new IllegalArgumentException("stack overflow");
+        }
+    }
+
+    private void adjust(int dir) {
+        mTop += dir * MATRIX_SIZE;
+    }
+
+    private final static int DEFAULT_MAX_DEPTH = 32;
+    private final static int MATRIX_SIZE = 16;
+    private float[] mMatrix;
+    private int mTop;
+    private float[] mTemp;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixTrackingGL.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixTrackingGL.java
new file mode 100644
index 0000000..a02761d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/MatrixTrackingGL.java
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics.spritetext;
+
+import android.util.Log;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL10Ext;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+/**
+ * Allows retrieving the current matrix even if the current OpenGL ES
+ * driver does not support retrieving the current matrix.
+ *
+ * Note: the actual matrix may differ from the retrieved matrix, due
+ * to differences in the way the math is implemented by GLMatrixWrapper
+ * as compared to the way the math is implemented by the OpenGL ES
+ * driver.
+ */
+class MatrixTrackingGL implements GL, GL10, GL10Ext, GL11, GL11Ext {
+    private GL10 mgl;
+    private GL10Ext mgl10Ext;
+    private GL11 mgl11;
+    private GL11Ext mgl11Ext;
+    private int mMatrixMode;
+    private MatrixStack mCurrent;
+    private MatrixStack mModelView;
+    private MatrixStack mTexture;
+    private MatrixStack mProjection;
+
+    private final static boolean _check = false;
+    ByteBuffer mByteBuffer;
+    FloatBuffer mFloatBuffer;
+    float[] mCheckA;
+    float[] mCheckB;
+
+    public MatrixTrackingGL(GL gl) {
+        mgl = (GL10) gl;
+        if (gl instanceof GL10Ext) {
+            mgl10Ext = (GL10Ext) gl;
+        }
+        if (gl instanceof GL11) {
+            mgl11 = (GL11) gl;
+        }
+        if (gl instanceof GL11Ext) {
+            mgl11Ext = (GL11Ext) gl;
+        }
+        mModelView = new MatrixStack();
+        mProjection = new MatrixStack();
+        mTexture = new MatrixStack();
+        mCurrent = mModelView;
+        mMatrixMode = GL10.GL_MODELVIEW;
+    }
+
+    // ---------------------------------------------------------------------
+    // GL10 methods:
+
+    public void glActiveTexture(int texture) {
+        mgl.glActiveTexture(texture);
+    }
+
+    public void glAlphaFunc(int func, float ref) {
+        mgl.glAlphaFunc(func, ref);
+    }
+
+    public void glAlphaFuncx(int func, int ref) {
+        mgl.glAlphaFuncx(func, ref);
+    }
+
+    public void glBindTexture(int target, int texture) {
+        mgl.glBindTexture(target, texture);
+    }
+
+    public void glBlendFunc(int sfactor, int dfactor) {
+        mgl.glBlendFunc(sfactor, dfactor);
+    }
+
+    public void glClear(int mask) {
+        mgl.glClear(mask);
+    }
+
+    public void glClearColor(float red, float green, float blue, float alpha) {
+        mgl.glClearColor(red, green, blue, alpha);
+    }
+
+    public void glClearColorx(int red, int green, int blue, int alpha) {
+        mgl.glClearColorx(red, green, blue, alpha);
+    }
+
+    public void glClearDepthf(float depth) {
+        mgl.glClearDepthf(depth);
+    }
+
+    public void glClearDepthx(int depth) {
+        mgl.glClearDepthx(depth);
+    }
+
+    public void glClearStencil(int s) {
+        mgl.glClearStencil(s);
+    }
+
+    public void glClientActiveTexture(int texture) {
+        mgl.glClientActiveTexture(texture);
+    }
+
+    public void glColor4f(float red, float green, float blue, float alpha) {
+        mgl.glColor4f(red, green, blue, alpha);
+    }
+
+    public void glColor4x(int red, int green, int blue, int alpha) {
+        mgl.glColor4x(red, green, blue, alpha);
+    }
+
+    public void glColorMask(boolean red, boolean green, boolean blue,
+            boolean alpha) {
+        mgl.glColorMask(red, green, blue, alpha);
+    }
+
+    public void glColorPointer(int size, int type, int stride, Buffer pointer) {
+        mgl.glColorPointer(size, type, stride, pointer);
+    }
+
+    public void glCompressedTexImage2D(int target, int level,
+            int internalformat, int width, int height, int border,
+            int imageSize, Buffer data) {
+        mgl.glCompressedTexImage2D(target, level, internalformat, width,
+                height, border, imageSize, data);
+    }
+
+    public void glCompressedTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int width, int height, int format, int imageSize,
+            Buffer data) {
+        mgl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width,
+                height, format, imageSize, data);
+    }
+
+    public void glCopyTexImage2D(int target, int level, int internalformat,
+            int x, int y, int width, int height, int border) {
+        mgl.glCopyTexImage2D(target, level, internalformat, x, y, width,
+                height, border);
+    }
+
+    public void glCopyTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int x, int y, int width, int height) {
+        mgl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
+                height);
+    }
+
+    public void glCullFace(int mode) {
+        mgl.glCullFace(mode);
+    }
+
+    public void glDeleteTextures(int n, int[] textures, int offset) {
+        mgl.glDeleteTextures(n, textures, offset);
+    }
+
+    public void glDeleteTextures(int n, IntBuffer textures) {
+        mgl.glDeleteTextures(n, textures);
+    }
+
+    public void glDepthFunc(int func) {
+        mgl.glDepthFunc(func);
+    }
+
+    public void glDepthMask(boolean flag) {
+        mgl.glDepthMask(flag);
+    }
+
+    public void glDepthRangef(float near, float far) {
+        mgl.glDepthRangef(near, far);
+    }
+
+    public void glDepthRangex(int near, int far) {
+        mgl.glDepthRangex(near, far);
+    }
+
+    public void glDisable(int cap) {
+        mgl.glDisable(cap);
+    }
+
+    public void glDisableClientState(int array) {
+        mgl.glDisableClientState(array);
+    }
+
+    public void glDrawArrays(int mode, int first, int count) {
+        mgl.glDrawArrays(mode, first, count);
+    }
+
+    public void glDrawElements(int mode, int count, int type, Buffer indices) {
+        mgl.glDrawElements(mode, count, type, indices);
+    }
+
+    public void glEnable(int cap) {
+        mgl.glEnable(cap);
+    }
+
+    public void glEnableClientState(int array) {
+        mgl.glEnableClientState(array);
+    }
+
+    public void glFinish() {
+        mgl.glFinish();
+    }
+
+    public void glFlush() {
+        mgl.glFlush();
+    }
+
+    public void glFogf(int pname, float param) {
+        mgl.glFogf(pname, param);
+    }
+
+    public void glFogfv(int pname, float[] params, int offset) {
+        mgl.glFogfv(pname, params, offset);
+    }
+
+    public void glFogfv(int pname, FloatBuffer params) {
+        mgl.glFogfv(pname, params);
+    }
+
+    public void glFogx(int pname, int param) {
+        mgl.glFogx(pname, param);
+    }
+
+    public void glFogxv(int pname, int[] params, int offset) {
+        mgl.glFogxv(pname, params, offset);
+    }
+
+    public void glFogxv(int pname, IntBuffer params) {
+        mgl.glFogxv(pname, params);
+    }
+
+    public void glFrontFace(int mode) {
+        mgl.glFrontFace(mode);
+    }
+
+    public void glFrustumf(float left, float right, float bottom, float top,
+            float near, float far) {
+        mCurrent.glFrustumf(left, right, bottom, top, near, far);
+        mgl.glFrustumf(left, right, bottom, top, near, far);
+        if ( _check) check();
+    }
+
+    public void glFrustumx(int left, int right, int bottom, int top, int near,
+            int far) {
+        mCurrent.glFrustumx(left, right, bottom, top, near, far);
+        mgl.glFrustumx(left, right, bottom, top, near, far);
+        if ( _check) check();
+    }
+
+    public void glGenTextures(int n, int[] textures, int offset) {
+        mgl.glGenTextures(n, textures, offset);
+    }
+
+    public void glGenTextures(int n, IntBuffer textures) {
+        mgl.glGenTextures(n, textures);
+    }
+
+    public int glGetError() {
+        int result = mgl.glGetError();
+        return result;
+    }
+
+    public void glGetIntegerv(int pname, int[] params, int offset) {
+        mgl.glGetIntegerv(pname, params, offset);
+    }
+
+    public void glGetIntegerv(int pname, IntBuffer params) {
+        mgl.glGetIntegerv(pname, params);
+    }
+
+    public String glGetString(int name) {
+        String result = mgl.glGetString(name);
+        return result;
+    }
+
+    public void glHint(int target, int mode) {
+        mgl.glHint(target, mode);
+    }
+
+    public void glLightModelf(int pname, float param) {
+        mgl.glLightModelf(pname, param);
+    }
+
+    public void glLightModelfv(int pname, float[] params, int offset) {
+        mgl.glLightModelfv(pname, params, offset);
+    }
+
+    public void glLightModelfv(int pname, FloatBuffer params) {
+        mgl.glLightModelfv(pname, params);
+    }
+
+    public void glLightModelx(int pname, int param) {
+        mgl.glLightModelx(pname, param);
+    }
+
+    public void glLightModelxv(int pname, int[] params, int offset) {
+        mgl.glLightModelxv(pname, params, offset);
+    }
+
+    public void glLightModelxv(int pname, IntBuffer params) {
+        mgl.glLightModelxv(pname, params);
+    }
+
+    public void glLightf(int light, int pname, float param) {
+        mgl.glLightf(light, pname, param);
+    }
+
+    public void glLightfv(int light, int pname, float[] params, int offset) {
+        mgl.glLightfv(light, pname, params, offset);
+    }
+
+    public void glLightfv(int light, int pname, FloatBuffer params) {
+        mgl.glLightfv(light, pname, params);
+    }
+
+    public void glLightx(int light, int pname, int param) {
+        mgl.glLightx(light, pname, param);
+    }
+
+    public void glLightxv(int light, int pname, int[] params, int offset) {
+        mgl.glLightxv(light, pname, params, offset);
+    }
+
+    public void glLightxv(int light, int pname, IntBuffer params) {
+        mgl.glLightxv(light, pname, params);
+    }
+
+    public void glLineWidth(float width) {
+        mgl.glLineWidth(width);
+    }
+
+    public void glLineWidthx(int width) {
+        mgl.glLineWidthx(width);
+    }
+
+    public void glLoadIdentity() {
+        mCurrent.glLoadIdentity();
+        mgl.glLoadIdentity();
+        if ( _check) check();
+    }
+
+    public void glLoadMatrixf(float[] m, int offset) {
+        mCurrent.glLoadMatrixf(m, offset);
+        mgl.glLoadMatrixf(m, offset);
+        if ( _check) check();
+    }
+
+    public void glLoadMatrixf(FloatBuffer m) {
+        int position = m.position();
+        mCurrent.glLoadMatrixf(m);
+        m.position(position);
+        mgl.glLoadMatrixf(m);
+        if ( _check) check();
+    }
+
+    public void glLoadMatrixx(int[] m, int offset) {
+        mCurrent.glLoadMatrixx(m, offset);
+        mgl.glLoadMatrixx(m, offset);
+        if ( _check) check();
+    }
+
+    public void glLoadMatrixx(IntBuffer m) {
+        int position = m.position();
+        mCurrent.glLoadMatrixx(m);
+        m.position(position);
+        mgl.glLoadMatrixx(m);
+        if ( _check) check();
+    }
+
+    public void glLogicOp(int opcode) {
+        mgl.glLogicOp(opcode);
+    }
+
+    public void glMaterialf(int face, int pname, float param) {
+        mgl.glMaterialf(face, pname, param);
+    }
+
+    public void glMaterialfv(int face, int pname, float[] params, int offset) {
+        mgl.glMaterialfv(face, pname, params, offset);
+    }
+
+    public void glMaterialfv(int face, int pname, FloatBuffer params) {
+        mgl.glMaterialfv(face, pname, params);
+    }
+
+    public void glMaterialx(int face, int pname, int param) {
+        mgl.glMaterialx(face, pname, param);
+    }
+
+    public void glMaterialxv(int face, int pname, int[] params, int offset) {
+        mgl.glMaterialxv(face, pname, params, offset);
+    }
+
+    public void glMaterialxv(int face, int pname, IntBuffer params) {
+        mgl.glMaterialxv(face, pname, params);
+    }
+
+    public void glMatrixMode(int mode) {
+        switch (mode) {
+        case GL10.GL_MODELVIEW:
+            mCurrent = mModelView;
+            break;
+        case GL10.GL_TEXTURE:
+            mCurrent = mTexture;
+            break;
+        case GL10.GL_PROJECTION:
+            mCurrent = mProjection;
+            break;
+        default:
+            throw new IllegalArgumentException("Unknown matrix mode: " + mode);
+        }
+        mgl.glMatrixMode(mode);
+        mMatrixMode = mode;
+        if ( _check) check();
+    }
+
+    public void glMultMatrixf(float[] m, int offset) {
+        mCurrent.glMultMatrixf(m, offset);
+        mgl.glMultMatrixf(m, offset);
+        if ( _check) check();
+    }
+
+    public void glMultMatrixf(FloatBuffer m) {
+        int position = m.position();
+        mCurrent.glMultMatrixf(m);
+        m.position(position);
+        mgl.glMultMatrixf(m);
+        if ( _check) check();
+    }
+
+    public void glMultMatrixx(int[] m, int offset) {
+        mCurrent.glMultMatrixx(m, offset);
+        mgl.glMultMatrixx(m, offset);
+        if ( _check) check();
+    }
+
+    public void glMultMatrixx(IntBuffer m) {
+        int position = m.position();
+        mCurrent.glMultMatrixx(m);
+        m.position(position);
+        mgl.glMultMatrixx(m);
+        if ( _check) check();
+    }
+
+    public void glMultiTexCoord4f(int target,
+            float s, float t, float r, float q) {
+        mgl.glMultiTexCoord4f(target, s, t, r, q);
+    }
+
+    public void glMultiTexCoord4x(int target, int s, int t, int r, int q) {
+        mgl.glMultiTexCoord4x(target, s, t, r, q);
+    }
+
+    public void glNormal3f(float nx, float ny, float nz) {
+        mgl.glNormal3f(nx, ny, nz);
+    }
+
+    public void glNormal3x(int nx, int ny, int nz) {
+        mgl.glNormal3x(nx, ny, nz);
+    }
+
+    public void glNormalPointer(int type, int stride, Buffer pointer) {
+        mgl.glNormalPointer(type, stride, pointer);
+    }
+
+    public void glOrthof(float left, float right, float bottom, float top,
+            float near, float far) {
+        mCurrent.glOrthof(left, right, bottom, top, near, far);
+        mgl.glOrthof(left, right, bottom, top, near, far);
+        if ( _check) check();
+    }
+
+    public void glOrthox(int left, int right, int bottom, int top, int near,
+            int far) {
+        mCurrent.glOrthox(left, right, bottom, top, near, far);
+        mgl.glOrthox(left, right, bottom, top, near, far);
+        if ( _check) check();
+    }
+
+    public void glPixelStorei(int pname, int param) {
+        mgl.glPixelStorei(pname, param);
+    }
+
+    public void glPointSize(float size) {
+        mgl.glPointSize(size);
+    }
+
+    public void glPointSizex(int size) {
+        mgl.glPointSizex(size);
+    }
+
+    public void glPolygonOffset(float factor, float units) {
+        mgl.glPolygonOffset(factor, units);
+    }
+
+    public void glPolygonOffsetx(int factor, int units) {
+        mgl.glPolygonOffsetx(factor, units);
+    }
+
+    public void glPopMatrix() {
+        mCurrent.glPopMatrix();
+        mgl.glPopMatrix();
+        if ( _check) check();
+    }
+
+    public void glPushMatrix() {
+        mCurrent.glPushMatrix();
+        mgl.glPushMatrix();
+        if ( _check) check();
+    }
+
+    public void glReadPixels(int x, int y, int width, int height, int format,
+            int type, Buffer pixels) {
+        mgl.glReadPixels(x, y, width, height, format, type, pixels);
+    }
+
+    public void glRotatef(float angle, float x, float y, float z) {
+        mCurrent.glRotatef(angle, x, y, z);
+        mgl.glRotatef(angle, x, y, z);
+        if ( _check) check();
+    }
+
+    public void glRotatex(int angle, int x, int y, int z) {
+        mCurrent.glRotatex(angle, x, y, z);
+        mgl.glRotatex(angle, x, y, z);
+        if ( _check) check();
+    }
+
+    public void glSampleCoverage(float value, boolean invert) {
+        mgl.glSampleCoverage(value, invert);
+    }
+
+    public void glSampleCoveragex(int value, boolean invert) {
+        mgl.glSampleCoveragex(value, invert);
+    }
+
+    public void glScalef(float x, float y, float z) {
+        mCurrent.glScalef(x, y, z);
+        mgl.glScalef(x, y, z);
+        if ( _check) check();
+    }
+
+    public void glScalex(int x, int y, int z) {
+        mCurrent.glScalex(x, y, z);
+        mgl.glScalex(x, y, z);
+        if ( _check) check();
+    }
+
+    public void glScissor(int x, int y, int width, int height) {
+        mgl.glScissor(x, y, width, height);
+    }
+
+    public void glShadeModel(int mode) {
+        mgl.glShadeModel(mode);
+    }
+
+    public void glStencilFunc(int func, int ref, int mask) {
+        mgl.glStencilFunc(func, ref, mask);
+    }
+
+    public void glStencilMask(int mask) {
+        mgl.glStencilMask(mask);
+    }
+
+    public void glStencilOp(int fail, int zfail, int zpass) {
+        mgl.glStencilOp(fail, zfail, zpass);
+    }
+
+    public void glTexCoordPointer(int size, int type,
+            int stride, Buffer pointer) {
+        mgl.glTexCoordPointer(size, type, stride, pointer);
+    }
+
+    public void glTexEnvf(int target, int pname, float param) {
+        mgl.glTexEnvf(target, pname, param);
+    }
+
+    public void glTexEnvfv(int target, int pname, float[] params, int offset) {
+        mgl.glTexEnvfv(target, pname, params, offset);
+    }
+
+    public void glTexEnvfv(int target, int pname, FloatBuffer params) {
+        mgl.glTexEnvfv(target, pname, params);
+    }
+
+    public void glTexEnvx(int target, int pname, int param) {
+        mgl.glTexEnvx(target, pname, param);
+    }
+
+    public void glTexEnvxv(int target, int pname, int[] params, int offset) {
+        mgl.glTexEnvxv(target, pname, params, offset);
+    }
+
+    public void glTexEnvxv(int target, int pname, IntBuffer params) {
+        mgl.glTexEnvxv(target, pname, params);
+    }
+
+    public void glTexImage2D(int target, int level, int internalformat,
+            int width, int height, int border, int format, int type,
+            Buffer pixels) {
+        mgl.glTexImage2D(target, level, internalformat, width, height, border,
+                format, type, pixels);
+    }
+
+    public void glTexParameterf(int target, int pname, float param) {
+        mgl.glTexParameterf(target, pname, param);
+    }
+
+    public void glTexParameterx(int target, int pname, int param) {
+        mgl.glTexParameterx(target, pname, param);
+    }
+
+    public void glTexParameteriv(int target, int pname, int[] params, int offset) {
+        mgl11.glTexParameteriv(target, pname, params, offset);
+    }
+
+    public void glTexParameteriv(int target, int pname, IntBuffer params) {
+        mgl11.glTexParameteriv(target, pname, params);
+    }
+
+    public void glTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int width, int height, int format, int type,
+            Buffer pixels) {
+        mgl.glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+                format, type, pixels);
+    }
+
+    public void glTranslatef(float x, float y, float z) {
+        mCurrent.glTranslatef(x, y, z);
+        mgl.glTranslatef(x, y, z);
+        if ( _check) check();
+    }
+
+    public void glTranslatex(int x, int y, int z) {
+        mCurrent.glTranslatex(x, y, z);
+        mgl.glTranslatex(x, y, z);
+        if ( _check) check();
+    }
+
+    public void glVertexPointer(int size, int type,
+            int stride, Buffer pointer) {
+        mgl.glVertexPointer(size, type, stride, pointer);
+    }
+
+    public void glViewport(int x, int y, int width, int height) {
+        mgl.glViewport(x, y, width, height);
+    }
+
+    public void glClipPlanef(int plane, float[] equation, int offset) {
+        mgl11.glClipPlanef(plane, equation, offset);
+    }
+
+    public void glClipPlanef(int plane, FloatBuffer equation) {
+        mgl11.glClipPlanef(plane, equation);
+    }
+
+    public void glClipPlanex(int plane, int[] equation, int offset) {
+        mgl11.glClipPlanex(plane, equation, offset);
+    }
+
+    public void glClipPlanex(int plane, IntBuffer equation) {
+        mgl11.glClipPlanex(plane, equation);
+    }
+
+    // Draw Texture Extension
+
+    public void glDrawTexfOES(float x, float y, float z,
+        float width, float height) {
+        mgl11Ext.glDrawTexfOES(x, y, z, width, height);
+    }
+
+    public void glDrawTexfvOES(float[] coords, int offset) {
+        mgl11Ext.glDrawTexfvOES(coords, offset);
+    }
+
+    public void glDrawTexfvOES(FloatBuffer coords) {
+        mgl11Ext.glDrawTexfvOES(coords);
+    }
+
+    public void glDrawTexiOES(int x, int y, int z, int width, int height) {
+        mgl11Ext.glDrawTexiOES(x, y, z, width, height);
+    }
+
+    public void glDrawTexivOES(int[] coords, int offset) {
+        mgl11Ext.glDrawTexivOES(coords, offset);
+    }
+
+    public void glDrawTexivOES(IntBuffer coords) {
+        mgl11Ext.glDrawTexivOES(coords);
+    }
+
+    public void glDrawTexsOES(short x, short y, short z,
+        short width, short height) {
+        mgl11Ext.glDrawTexsOES(x, y, z, width, height);
+    }
+
+    public void glDrawTexsvOES(short[] coords, int offset) {
+        mgl11Ext.glDrawTexsvOES(coords, offset);
+    }
+
+    public void glDrawTexsvOES(ShortBuffer coords) {
+        mgl11Ext.glDrawTexsvOES(coords);
+    }
+
+    public void glDrawTexxOES(int x, int y, int z, int width, int height) {
+        mgl11Ext.glDrawTexxOES(x, y, z, width, height);
+    }
+
+    public void glDrawTexxvOES(int[] coords, int offset) {
+        mgl11Ext.glDrawTexxvOES(coords, offset);
+    }
+
+    public void glDrawTexxvOES(IntBuffer coords) {
+        mgl11Ext.glDrawTexxvOES(coords);
+    }
+
+    public int glQueryMatrixxOES(int[] mantissa, int mantissaOffset,
+        int[] exponent, int exponentOffset) {
+        return mgl10Ext.glQueryMatrixxOES(mantissa, mantissaOffset,
+            exponent, exponentOffset);
+    }
+
+    public int glQueryMatrixxOES(IntBuffer mantissa, IntBuffer exponent) {
+        return mgl10Ext.glQueryMatrixxOES(mantissa, exponent);
+    }
+
+    // Unsupported GL11 methods
+
+    public void glBindBuffer(int target, int buffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBufferData(int target, int size, Buffer data, int usage) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBufferSubData(int target, int offset, int size, Buffer data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glColor4ub(byte red, byte green, byte blue, byte alpha) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteBuffers(int n, int[] buffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteBuffers(int n, IntBuffer buffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenBuffers(int n, int[] buffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenBuffers(int n, IntBuffer buffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBooleanv(int pname, boolean[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBooleanv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBufferParameteriv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBufferParameteriv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanef(int pname, float[] eqn, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanef(int pname, FloatBuffer eqn) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanex(int pname, int[] eqn, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanex(int pname, IntBuffer eqn) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFixedv(int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFixedv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFloatv(int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFloatv(int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightfv(int light, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightfv(int light, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightxv(int light, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightxv(int light, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialfv(int face, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialfv(int face, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialxv(int face, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialxv(int face, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnviv(int env, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnviv(int env, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnvxv(int env, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnvxv(int env, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterfv(int target, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterfv(int target, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameteriv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameteriv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterxv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterxv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsBuffer(int buffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsEnabled(int cap) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsTexture(int texture) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterf(int pname, float param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterfv(int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterfv(int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterx(int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterxv(int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterxv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointSizePointerOES(int type, int stride, Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnvi(int target, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnviv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnviv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterfv(int target, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterfv(int target, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameteri(int target, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterxv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterxv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glColorPointer(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDrawElements(int mode, int count, int type, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetPointerv(int pname, Buffer[] params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glNormalPointer(int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexCoordPointer(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glVertexPointer(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glCurrentPaletteMatrixOES(int matrixpaletteindex) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glLoadPaletteFromModelViewMatrixOES() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glMatrixIndexPointerOES(int size, int type, int stride,
+            Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glMatrixIndexPointerOES(int size, int type, int stride,
+            int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glWeightPointerOES(int size, int type, int stride,
+            Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glWeightPointerOES(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Get the current matrix
+     */
+
+    public void getMatrix(float[] m, int offset) {
+        mCurrent.getMatrix(m, offset);
+    }
+
+    /**
+     * Get the current matrix mode
+     */
+
+    public int getMatrixMode() {
+        return mMatrixMode;
+    }
+
+    private void check() {
+        int oesMode;
+        switch (mMatrixMode) {
+        case GL_MODELVIEW:
+            oesMode = GL11.GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES;
+            break;
+        case GL_PROJECTION:
+            oesMode = GL11.GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES;
+            break;
+        case GL_TEXTURE:
+            oesMode = GL11.GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES;
+            break;
+        default:
+            throw new IllegalArgumentException("Unknown matrix mode");
+        }
+
+        if ( mByteBuffer == null) {
+            mCheckA = new float[16];
+            mCheckB = new float[16];
+            mByteBuffer = ByteBuffer.allocateDirect(64);
+            mByteBuffer.order(ByteOrder.nativeOrder());
+            mFloatBuffer = mByteBuffer.asFloatBuffer();
+        }
+        mgl.glGetIntegerv(oesMode, mByteBuffer.asIntBuffer());
+        for(int i = 0; i < 16; i++) {
+            mCheckB[i] = mFloatBuffer.get(i);
+        }
+        mCurrent.getMatrix(mCheckA, 0);
+
+        boolean fail = false;
+        for(int i = 0; i < 16; i++) {
+            if (mCheckA[i] != mCheckB[i]) {
+                Log.d("GLMatWrap", "i:" + i + " a:" + mCheckA[i]
+                + " a:" + mCheckB[i]);
+                fail = true;
+            }
+        }
+        if (fail) {
+            throw new IllegalArgumentException("Matrix math difference.");
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/NumericSprite.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/NumericSprite.java
new file mode 100644
index 0000000..e70dfda
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/NumericSprite.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 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.graphics.spritetext;
+
+import javax.microedition.khronos.opengles.GL10;
+
+import android.graphics.Paint;
+
+public class NumericSprite {
+    public NumericSprite() {
+        mText = "";
+        mLabelMaker = null;
+    }
+
+    public void initialize(GL10 gl, Paint paint) {
+        int height = roundUpPower2((int) paint.getFontSpacing());
+        final float interDigitGaps = 9 * 1.0f;
+        int width = roundUpPower2((int) (interDigitGaps + paint.measureText(sStrike)));
+        mLabelMaker = new LabelMaker(true, width, height);
+        mLabelMaker.initialize(gl);
+        mLabelMaker.beginAdding(gl);
+        for (int i = 0; i < 10; i++) {
+            String digit = sStrike.substring(i, i+1);
+            mLabelId[i] = mLabelMaker.add(gl, digit, paint);
+            mWidth[i] = (int) Math.ceil(mLabelMaker.getWidth(i));
+        }
+        mLabelMaker.endAdding(gl);
+    }
+
+    public void shutdown(GL10 gl) {
+        mLabelMaker.shutdown(gl);
+        mLabelMaker = null;
+    }
+
+    /**
+     * Find the smallest power of two >= the input value.
+     * (Doesn't work for negative numbers.)
+     */
+    private int roundUpPower2(int x) {
+        x = x - 1;
+        x = x | (x >> 1);
+        x = x | (x >> 2);
+        x = x | (x >> 4);
+        x = x | (x >> 8);
+        x = x | (x >>16);
+        return x + 1;
+    }
+
+    public void setValue(int value) {
+        mText = format(value);
+    }
+
+    public void draw(GL10 gl, float x, float y,
+            float viewWidth, float viewHeight) {
+        int length = mText.length();
+        mLabelMaker.beginDrawing(gl, viewWidth, viewHeight);
+        for(int i = 0; i < length; i++) {
+            char c = mText.charAt(i);
+            int digit = c - '0';
+            mLabelMaker.draw(gl, x, y, mLabelId[digit]);
+            x += mWidth[digit];
+        }
+        mLabelMaker.endDrawing(gl);
+    }
+
+    public float width() {
+        float width = 0.0f;
+        int length = mText.length();
+        for(int i = 0; i < length; i++) {
+            char c = mText.charAt(i);
+            width += mWidth[c - '0'];
+        }
+        return width;
+    }
+
+    private String format(int value) {
+        return Integer.toString(value);
+    }
+
+    private LabelMaker mLabelMaker;
+    private String mText;
+    private int[] mWidth = new int[10];
+    private int[] mLabelId = new int[10];
+    private final static String sStrike = "0123456789";
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/Projector.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/Projector.java
new file mode 100644
index 0000000..b52fa3e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/Projector.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics.spritetext;
+
+import android.opengl.Matrix;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A utility that projects
+ *
+ */
+class Projector {
+    public Projector() {
+        mMVP = new float[16];
+        mV = new float[4];
+        mGrabber = new MatrixGrabber();
+    }
+
+    public void setCurrentView(int x, int y, int width, int height) {
+        mX = x;
+        mY = y;
+        mViewWidth = width;
+        mViewHeight = height;
+    }
+
+    public void project(float[] obj, int objOffset, float[] win, int winOffset) {
+        if (!mMVPComputed) {
+            Matrix.multiplyMM(mMVP, 0, mGrabber.mProjection, 0, mGrabber.mModelView, 0);
+            mMVPComputed = true;
+        }
+
+        Matrix.multiplyMV(mV, 0, mMVP, 0, obj, objOffset);
+
+        float rw = 1.0f / mV[3];
+
+        win[winOffset] = mX + mViewWidth * (mV[0] * rw + 1.0f) * 0.5f;
+        win[winOffset + 1] = mY + mViewHeight * (mV[1] * rw + 1.0f) * 0.5f;
+        win[winOffset + 2] = (mV[2] * rw + 1.0f) * 0.5f;
+    }
+
+    /**
+     * Get the current projection matrix. Has the side-effect of
+     * setting current matrix mode to GL_PROJECTION
+     * @param gl
+     */
+    public void getCurrentProjection(GL10 gl) {
+        mGrabber.getCurrentProjection(gl);
+        mMVPComputed = false;
+    }
+
+    /**
+     * Get the current model view matrix. Has the side-effect of
+     * setting current matrix mode to GL_MODELVIEW
+     * @param gl
+     */
+    public void getCurrentModelView(GL10 gl) {
+        mGrabber.getCurrentModelView(gl);
+        mMVPComputed = false;
+    }
+
+    private MatrixGrabber mGrabber;
+    private boolean mMVPComputed;
+    private float[] mMVP;
+    private float[] mV;
+    private int mX;
+    private int mY;
+    private int mViewWidth;
+    private int mViewHeight;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextActivity.java
new file mode 100644
index 0000000..1e58dae
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 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.graphics.spritetext;
+
+import javax.microedition.khronos.opengles.GL;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class SpriteTextActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mGLSurfaceView = new GLSurfaceView(this);
+        mGLSurfaceView.setGLWrapper(new GLSurfaceView.GLWrapper() {
+            public GL wrap(GL gl) {
+                return new MatrixTrackingGL(gl);
+            }});
+        mGLSurfaceView.setRenderer(new SpriteTextRenderer(this));
+        setContentView(mGLSurfaceView);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGLSurfaceView.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGLSurfaceView.onResume();
+    }
+
+    private GLSurfaceView mGLSurfaceView;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java
new file mode 100644
index 0000000..b9369cd
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2008 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.graphics.spritetext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Paint;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.os.SystemClock;
+
+import com.example.android.apis.R;
+
+public class SpriteTextRenderer implements GLSurfaceView.Renderer{
+
+    public SpriteTextRenderer(Context context) {
+        mContext = context;
+        mTriangle = new Triangle();
+        mProjector = new Projector();
+        mLabelPaint = new Paint();
+        mLabelPaint.setTextSize(32);
+        mLabelPaint.setAntiAlias(true);
+        mLabelPaint.setARGB(0xff, 0x00, 0x00, 0x00);
+    }
+
+    public int[] getConfigSpec() {
+        // We don't need a depth buffer, and don't care about our
+        // color depth.
+        int[] configSpec = {
+                EGL10.EGL_DEPTH_SIZE, 0,
+                EGL10.EGL_NONE
+        };
+        return configSpec;
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                GL10.GL_FASTEST);
+
+        gl.glClearColor(.5f, .5f, .5f, 1);
+        gl.glShadeModel(GL10.GL_SMOOTH);
+        gl.glEnable(GL10.GL_DEPTH_TEST);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+
+        /*
+         * Create our texture. This has to be done each time the
+         * surface is created.
+         */
+
+        int[] textures = new int[1];
+        gl.glGenTextures(1, textures, 0);
+
+        mTextureID = textures[0];
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+                GL10.GL_NEAREST);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
+                GL10.GL_TEXTURE_MAG_FILTER,
+                GL10.GL_LINEAR);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                GL10.GL_CLAMP_TO_EDGE);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                GL10.GL_CLAMP_TO_EDGE);
+
+        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                GL10.GL_REPLACE);
+
+        InputStream is = mContext.getResources()
+                .openRawResource(R.drawable.robot);
+        Bitmap bitmap;
+        try {
+            bitmap = BitmapFactory.decodeStream(is);
+        } finally {
+            try {
+                is.close();
+            } catch(IOException e) {
+                // Ignore.
+            }
+        }
+
+        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
+        bitmap.recycle();
+
+        if (mLabels != null) {
+            mLabels.shutdown(gl);
+        } else {
+            mLabels = new LabelMaker(true, 256, 64);
+        }
+        mLabels.initialize(gl);
+        mLabels.beginAdding(gl);
+        mLabelA = mLabels.add(gl, "A", mLabelPaint);
+        mLabelB = mLabels.add(gl, "B", mLabelPaint);
+        mLabelC = mLabels.add(gl, "C", mLabelPaint);
+        mLabelMsPF = mLabels.add(gl, "ms/f", mLabelPaint);
+        mLabels.endAdding(gl);
+
+        if (mNumericSprite != null) {
+            mNumericSprite.shutdown(gl);
+        } else {
+            mNumericSprite = new NumericSprite();
+        }
+        mNumericSprite.initialize(gl, mLabelPaint);
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                GL10.GL_MODULATE);
+
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+
+        GLU.gluLookAt(gl, 0.0f, 0.0f, -2.5f,
+                0.0f, 0.0f, 0.0f,
+                0.0f, 1.0f, 0.0f);
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+        gl.glActiveTexture(GL10.GL_TEXTURE0);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                GL10.GL_REPEAT);
+        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                GL10.GL_REPEAT);
+
+        long time = SystemClock.uptimeMillis() % 4000L;
+        float angle = 0.090f * ((int) time);
+
+        gl.glRotatef(angle, 0, 0, 1.0f);
+        gl.glScalef(2.0f, 2.0f, 2.0f);
+
+        mTriangle.draw(gl);
+
+        mProjector.getCurrentModelView(gl);
+        mLabels.beginDrawing(gl, mWidth, mHeight);
+        drawLabel(gl, 0, mLabelA);
+        drawLabel(gl, 1, mLabelB);
+        drawLabel(gl, 2, mLabelC);
+        float msPFX = mWidth - mLabels.getWidth(mLabelMsPF) - 1;
+        mLabels.draw(gl, msPFX, 0, mLabelMsPF);
+        mLabels.endDrawing(gl);
+
+        drawMsPF(gl, msPFX);
+    }
+
+    private void drawMsPF(GL10 gl, float rightMargin) {
+        long time = SystemClock.uptimeMillis();
+        if (mStartTime == 0) {
+            mStartTime = time;
+        }
+        if (mFrames++ == SAMPLE_PERIOD_FRAMES) {
+            mFrames = 0;
+            long delta = time - mStartTime;
+            mStartTime = time;
+            mMsPerFrame = (int) (delta * SAMPLE_FACTOR);
+        }
+        if (mMsPerFrame > 0) {
+            mNumericSprite.setValue(mMsPerFrame);
+            float numWidth = mNumericSprite.width();
+            float x = rightMargin - numWidth;
+            mNumericSprite.draw(gl, x, 0, mWidth, mHeight);
+        }
+    }
+
+    private void drawLabel(GL10 gl, int triangleVertex, int labelId) {
+        float x = mTriangle.getX(triangleVertex);
+        float y = mTriangle.getY(triangleVertex);
+        mScratch[0] = x;
+        mScratch[1] = y;
+        mScratch[2] = 0.0f;
+        mScratch[3] = 1.0f;
+        mProjector.project(mScratch, 0, mScratch, 4);
+        float sx = mScratch[4];
+        float sy = mScratch[5];
+        float height = mLabels.getHeight(labelId);
+        float width = mLabels.getWidth(labelId);
+        float tx = sx - width * 0.5f;
+        float ty = sy - height * 0.5f;
+        mLabels.draw(gl, tx, ty, labelId);
+    }
+
+    public void onSurfaceChanged(GL10 gl, int w, int h) {
+        mWidth = w;
+        mHeight = h;
+        gl.glViewport(0, 0, w, h);
+        mProjector.setCurrentView(0, 0, w, h);
+
+        /*
+        * Set our projection matrix. This doesn't have to be done
+        * each time we draw, but usually a new projection needs to
+        * be set when the viewport is resized.
+        */
+
+        float ratio = (float) w / h;
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+        mProjector.getCurrentProjection(gl);
+    }
+
+    private int mWidth;
+    private int mHeight;
+    private Context mContext;
+    private Triangle mTriangle;
+    private int mTextureID;
+    private int mFrames;
+    private int mMsPerFrame;
+    private final static int SAMPLE_PERIOD_FRAMES = 12;
+    private final static float SAMPLE_FACTOR = 1.0f / SAMPLE_PERIOD_FRAMES;
+    private long mStartTime;
+    private LabelMaker mLabels;
+    private Paint mLabelPaint;
+    private int mLabelA;
+    private int mLabelB;
+    private int mLabelC;
+    private int mLabelMsPF;
+    private Projector mProjector;
+    private NumericSprite mNumericSprite;
+    private float[] mScratch = new float[8];
+}
+
+class Triangle {
+    public Triangle() {
+
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct, i.e., they must be placed on the
+        // native heap where the garbage collector cannot
+        // move them.
+        //
+        // Buffers with multi-byte datatypes (e.g., short, int, float)
+        // must have their byte order set to native order
+
+        ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4);
+        vbb.order(ByteOrder.nativeOrder());
+        mFVertexBuffer = vbb.asFloatBuffer();
+
+        ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
+        tbb.order(ByteOrder.nativeOrder());
+        mTexBuffer = tbb.asFloatBuffer();
+
+        ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
+        ibb.order(ByteOrder.nativeOrder());
+        mIndexBuffer = ibb.asShortBuffer();
+
+        for (int i = 0; i < VERTS; i++) {
+            for(int j = 0; j < 3; j++) {
+                mFVertexBuffer.put(sCoords[i*3+j]);
+            }
+        }
+
+        for (int i = 0; i < VERTS; i++) {
+            for(int j = 0; j < 2; j++) {
+                mTexBuffer.put(sCoords[i*3+j] * 2.0f + 0.5f);
+            }
+        }
+
+        for(int i = 0; i < VERTS; i++) {
+            mIndexBuffer.put((short) i);
+        }
+
+        mFVertexBuffer.position(0);
+        mTexBuffer.position(0);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl) {
+        gl.glFrontFace(GL10.GL_CCW);
+        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
+        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, VERTS,
+                GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
+    }
+
+    public float getX(int vertex) {
+        return sCoords[3*vertex];
+    }
+
+    public float getY(int vertex) {
+        return sCoords[3*vertex+1];
+    }
+
+    private final static int VERTS = 3;
+
+    private FloatBuffer mFVertexBuffer;
+    private FloatBuffer mTexBuffer;
+    private ShortBuffer mIndexBuffer;
+    // A unit-sided equalateral triangle centered on the origin.
+    private final static float[] sCoords = {
+            // X, Y, Z
+            -0.5f, -0.25f, 0,
+             0.5f, -0.25f, 0,
+             0.0f,  0.559016994f, 0
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo.java b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo.java
new file mode 100644
index 0000000..4b89167
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo.java
@@ -0,0 +1,86 @@
+package com.example.android.apis.media;
+
+import com.example.android.apis.R;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class MediaPlayerDemo extends Activity {
+    private Button mlocalvideo;
+    private Button mresourcesvideo;
+    private Button mstreamvideo;
+    private Button mlocalaudio;
+    private Button mresourcesaudio;
+    private Button mstreamaudio;
+    private static final String MEDIA = "media";
+    private static final int LOCAL_AUDIO = 1;
+    private static final int STREAM_AUDIO = 2;
+    private static final int RESOURCES_AUDIO = 3;
+    private static final int LOCAL_VIDEO = 4;
+    private static final int STREAM_VIDEO = 5;
+    private static final int RESOURCES_VIDEO = 6;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        // TODO Auto-generated method stub
+        super.onCreate(icicle);
+        setContentView(R.layout.mediaplayer_1);
+        mlocalaudio = (Button) findViewById(R.id.localaudio);
+        mlocalaudio.setOnClickListener(mLocalAudioListener);
+        mresourcesaudio = (Button) findViewById(R.id.resourcesaudio);
+        mresourcesaudio.setOnClickListener(mResourcesAudioListener);
+
+        mlocalvideo = (Button) findViewById(R.id.localvideo);
+        mlocalvideo.setOnClickListener(mLocalVideoListener);
+        mstreamvideo = (Button) findViewById(R.id.streamvideo);
+        mstreamvideo.setOnClickListener(mStreamVideoListener);
+    }
+
+    private OnClickListener mLocalAudioListener = new OnClickListener() {
+        public void onClick(View v) {
+            Intent intent =
+                    new Intent(MediaPlayerDemo.this.getApplication(),
+                            MediaPlayerDemo_Audio.class);
+            intent.putExtra(MEDIA, LOCAL_AUDIO);
+            startActivity(intent);
+
+        }
+    };
+    private OnClickListener mResourcesAudioListener = new OnClickListener() {
+        public void onClick(View v) {
+            Intent intent =
+                    new Intent(MediaPlayerDemo.this.getApplication(),
+                            MediaPlayerDemo_Audio.class);
+            intent.putExtra(MEDIA, RESOURCES_AUDIO);
+            startActivity(intent);
+
+        }
+    };
+
+    private OnClickListener mLocalVideoListener = new OnClickListener() {
+        public void onClick(View v) {
+            Intent intent =
+                    new Intent(MediaPlayerDemo.this,
+                            MediaPlayerDemo_Video.class);
+            intent.putExtra(MEDIA, LOCAL_VIDEO);
+            startActivity(intent);
+
+        }
+    };
+    private OnClickListener mStreamVideoListener = new OnClickListener() {
+        public void onClick(View v) {
+            Intent intent =
+                    new Intent(MediaPlayerDemo.this,
+                            MediaPlayerDemo_Video.class);
+            intent.putExtra(MEDIA, STREAM_VIDEO);
+            startActivity(intent);
+
+        }
+    };
+
+
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Audio.java b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Audio.java
new file mode 100644
index 0000000..39930f6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Audio.java
@@ -0,0 +1,85 @@
+package com.example.android.apis.media;
+
+import android.app.Activity;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.example.android.apis.R;
+
+public class MediaPlayerDemo_Audio extends Activity {
+
+    private static final String TAG = "MediaPlayerDemo";
+    private MediaPlayer mMediaPlayer;
+    private static final String MEDIA = "media";
+    private static final int LOCAL_AUDIO = 1;
+    private static final int STREAM_AUDIO = 2;
+    private static final int RESOURCES_AUDIO = 3;
+    private static final int LOCAL_VIDEO = 4;
+    private static final int STREAM_VIDEO = 5;
+    private String path;
+
+    private TextView tx;
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        tx = new TextView(this);
+        setContentView(tx);
+        Bundle extras = getIntent().getExtras();
+        playAudio(extras.getInt(MEDIA));
+    }
+
+    private void playAudio(Integer media) {
+        try {
+            switch (media) {
+                case LOCAL_AUDIO:
+                    /**
+                     * TODO: Set the path variable to a local audio file path.
+                     */
+                    path = "";
+                    if (path == "") {
+                        // Tell the user to provide an audio file URL.
+                        Toast
+                                .makeText(
+                                        MediaPlayerDemo_Audio.this,
+                                        "Please edit MediaPlayer_Audio Activity, "
+                                                + "and set the path variable to your audio file path."
+                                                + " Your audio file must be stored on sdcard.",
+                                        Toast.LENGTH_LONG).show();
+
+                    }
+                    mMediaPlayer = new MediaPlayer();
+                    mMediaPlayer.setDataSource(path);
+                    mMediaPlayer.prepare();
+                    mMediaPlayer.start();
+                    break;
+                case RESOURCES_AUDIO:
+                    /**
+                     * TODO: Upload a audio file to res/raw folder and provide
+                     * its resid in MediaPlayer.create() method.
+                     */
+                    mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
+                    mMediaPlayer.start();
+
+            }
+            tx.setText("Playing audio...");
+
+        } catch (Exception e) {
+            Log.e(TAG, "error: " + e.getMessage(), e);
+        }
+
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        // TODO Auto-generated method stub
+        if (mMediaPlayer != null) {
+            mMediaPlayer.release();
+            mMediaPlayer = null;
+        }
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java
new file mode 100644
index 0000000..fd3c486
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java
@@ -0,0 +1,169 @@
+package com.example.android.apis.media;
+
+import com.example.android.apis.R;
+import com.example.android.apis.app.AlarmController;
+
+import android.app.Activity;
+import android.graphics.PixelFormat;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnBufferingUpdateListener;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+
+public class MediaPlayerDemo_Video extends Activity implements
+        OnBufferingUpdateListener, OnCompletionListener,
+        MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {
+
+    private static final String TAG = "MediaPlayerDemo";
+    private int mVideoWidth;
+    private int mVideoHeight;
+    private MediaPlayer mMediaPlayer;
+    private SurfaceView mPreview;
+    private SurfaceHolder holder;
+    private String path;
+    private Bundle extras;
+    private static final String MEDIA = "media";
+    private static final int LOCAL_AUDIO = 1;
+    private static final int STREAM_AUDIO = 2;
+    private static final int RESOURCES_AUDIO = 3;
+    private static final int LOCAL_VIDEO = 4;
+    private static final int STREAM_VIDEO = 5;
+
+    /**
+     * 
+     * Called when the activity is first created.
+     */
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.mediaplayer_2);
+        mPreview = (SurfaceView) findViewById(R.id.surface);
+        holder = mPreview.getHolder();
+        holder.addCallback(this);
+        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+        extras = getIntent().getExtras();
+
+    }
+
+    private void playVideo(Integer Media) {
+        try {
+
+            switch (Media) {
+                case LOCAL_VIDEO:
+                    /*
+                     * TODO: Set the path variable to a local media file path.
+                     */
+                    path = "";
+                    if (path == "") {
+                        // Tell the user to provide a media file URL.
+                        Toast
+                                .makeText(
+                                        MediaPlayerDemo_Video.this,
+                                        "Please edit MediaPlayerDemo_Video Activity, "
+                                                + "and set the path variable to your media file path."
+                                                + " Your media file must be stored on sdcard.",
+                                        Toast.LENGTH_LONG).show();
+
+                    }
+                    break;
+                case STREAM_VIDEO:
+                    /*
+                     * TODO: Set path variable to progressive streamable mp4 or
+                     * 3gpp format URL. Http protocol should be used.
+                     * Mediaplayer can only play "progressive streamable
+                     * contents" which basically means: 1. the movie atom has to
+                     * precede all the media data atoms. 2. The clip has to be
+                     * reasonably interleaved.
+                     * 
+                     */
+                    path = "";
+                    if (path == "") {
+                        // Tell the user to provide a media file URL.
+                        Toast
+                                .makeText(
+                                        MediaPlayerDemo_Video.this,
+                                        "Please edit MediaPlayerDemo_Video Activity,"
+                                                + " and set the path variable to your media file URL.",
+                                        Toast.LENGTH_LONG).show();
+
+                    }
+
+                    break;
+
+
+            }
+
+            // Create a new media player and set the listeners
+            mMediaPlayer = new MediaPlayer();
+            mMediaPlayer.setDataSource(path);
+            mMediaPlayer.setDisplay(holder);
+            mMediaPlayer.prepare();
+            mMediaPlayer.setOnBufferingUpdateListener(this);
+            mMediaPlayer.setOnCompletionListener(this);
+            mMediaPlayer.setOnPreparedListener(this);
+            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+
+
+        } catch (Exception e) {
+            Log.e(TAG, "error: " + e.getMessage(), e);
+        }
+    }
+
+    public void onBufferingUpdate(MediaPlayer arg0, int percent) {
+        Log.d(TAG, "onBufferingUpdate percent:" + percent);
+
+    }
+
+    public void onCompletion(MediaPlayer arg0) {
+        Log.d(TAG, "onCompletion called");
+    }
+
+    public void onPrepared(MediaPlayer mediaplayer) {
+        Log.d(TAG, "onPrepared called");
+        mVideoWidth = mMediaPlayer.getVideoWidth();
+        mVideoHeight = mMediaPlayer.getVideoHeight();
+        if (mVideoWidth != 0 && mVideoHeight != 0) {
+            holder.setFixedSize(mVideoWidth, mVideoHeight);
+            mMediaPlayer.start();
+        }
+
+    }
+
+    public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
+        Log.d(TAG, "surfaceChanged called");
+
+    }
+
+    public void surfaceDestroyed(SurfaceHolder surfaceholder) {
+        Log.d(TAG, "surfaceDestroyed called");
+    }
+
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        // TODO Auto-generated method stub
+        Log.d(TAG, "surfaceCreated called");
+        playVideo(extras.getInt(MEDIA));
+
+
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        // TODO Auto-generated method stub
+        if (mMediaPlayer != null) {
+            mMediaPlayer.release();
+            mMediaPlayer = null;
+        }
+
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/media/VideoViewDemo.java b/samples/ApiDemos/src/com/example/android/apis/media/VideoViewDemo.java
new file mode 100644
index 0000000..a4fcf5f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/media/VideoViewDemo.java
@@ -0,0 +1,48 @@
+package com.example.android.apis.media;
+
+import com.example.android.apis.R;
+import android.app.Activity;
+import android.graphics.PixelFormat;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.MediaController;
+import android.widget.Toast;
+import android.widget.VideoView;
+
+public class VideoViewDemo extends Activity {
+
+    /**
+     * TODO: Set the path variable to a streaming video URL or a local media
+     * file path.
+     */
+    private String path = "";
+    private VideoView mVideoView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.videoview);
+        mVideoView = (VideoView) findViewById(R.id.surface_view);
+
+        if (path == "") {
+            // Tell the user to provide a media file URL/path.
+            Toast.makeText(
+                    VideoViewDemo.this,
+                    "Please edit VideoViewDemo Activity, and set path"
+                            + " variable to your media file URL/path",
+                    Toast.LENGTH_LONG).show();
+
+        } else {
+
+            /*
+             * Alternatively,for streaming media you can use
+             * mVideoView.setVideoURI(Uri.parse(URLstring));
+             */
+            mVideoView.setVideoPath(path);
+            mVideoView.setMediaController(new MediaController(this));
+            mVideoView.requestFocus();
+
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/os/MorseCode.java b/samples/ApiDemos/src/com/example/android/apis/os/MorseCode.java
new file mode 100644
index 0000000..dafa192
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/os/MorseCode.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.os;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.view.View;
+import android.widget.TextView;
+import com.example.android.apis.R;
+
+/**
+ * <h3>App that vibrates the vibrator with the Morse Code for a string.</h3>
+
+<p>This demonstrates the {@link android.os.Vibrator android.os.Vibrator} class.
+
+<h4>Demo</h4>
+OS / Morse Code Vibrator
+ 
+<h4>Source files</h4>
+ * <table class="LinkTable">
+ *         <tr>
+ *             <td >src/com.example.android.apis/os/MorseCode.java</td>
+ *             <td >The Morse Code Vibrator</td>
+ *         </tr>
+ *         <tr>
+ *             <td >res/any/layout/morse_code.xml</td>
+ *             <td >Defines contents of the screen</td>
+ *         </tr>
+ * </table> 
+ */
+public class MorseCode extends Activity
+{
+    /** Tag string for our debug logs */
+    private static final String TAG = "MorseCode";
+
+    /** Our text view */
+    private TextView mTextView;
+
+    ;
+
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+    {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // See assets/res/any/layout/hello_world.xml for this
+        // view layout definition, which is being set here as
+        // the content of our screen.
+        setContentView(R.layout.morse_code);
+
+        // Set the OnClickListener for the button so we see when it's pressed.
+        findViewById(R.id.button).setOnClickListener(mClickListener);
+
+        // Save the text view so we don't have to look it up each time
+        mTextView = (TextView)findViewById(R.id.text);
+    }
+
+    /** Called when the button is pushed */
+    View.OnClickListener mClickListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            // Get the text out of the view
+            String text = mTextView.getText().toString();
+
+            // convert it using the function defined above.  See the docs for
+            // android.os.Vibrator for more info about the format of this array
+            long[] pattern = MorseCodeConverter.pattern(text);
+
+            // Start the vibration
+            Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
+            vibrator.vibrate(pattern, -1);
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/os/MorseCodeConverter.java b/samples/ApiDemos/src/com/example/android/apis/os/MorseCodeConverter.java
new file mode 100644
index 0000000..c68fab9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/os/MorseCodeConverter.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.os;
+
+/** Class that implements the text to morse code coversion */
+class MorseCodeConverter {
+    private static final long SPEED_BASE = 100;
+    static final long DOT = SPEED_BASE;
+    static final long DASH = SPEED_BASE * 3;
+    static final long GAP = SPEED_BASE;
+    static final long LETTER_GAP = SPEED_BASE * 3;
+    static final long WORD_GAP = SPEED_BASE * 7;
+
+    /** The characters from 'A' to 'Z' */
+    private static final long[][] LETTERS = new long[][] {
+        /* A */ new long[] { DOT, GAP, DASH },
+        /* B */ new long[] { DASH, GAP, DOT, GAP, DOT, GAP, DOT },
+        /* C */ new long[] { DASH, GAP, DOT, GAP, DASH, GAP, DOT },
+        /* D */ new long[] { DASH, GAP, DOT, GAP, DOT },
+        /* E */ new long[] { DOT },
+        /* F */ new long[] { DOT, GAP, DOT, GAP, DASH, GAP, DOT },
+        /* G */ new long[] { DASH, GAP, DASH, GAP, DOT },
+        /* H */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DOT },
+        /* I */ new long[] { DOT, GAP, DOT },
+        /* J */ new long[] { DOT, GAP, DASH, GAP, DASH, GAP, DASH },
+        /* K */ new long[] { DASH, GAP, DOT, GAP, DASH },
+        /* L */ new long[] { DOT, GAP, DASH, GAP, DOT, GAP, DOT },
+        /* M */ new long[] { DASH, GAP, DASH },
+        /* N */ new long[] { DASH, GAP, DOT },
+        /* O */ new long[] { DASH, GAP, DASH, GAP, DASH },
+        /* P */ new long[] { DOT, GAP, DASH, GAP, DASH, GAP, DOT },
+        /* Q */ new long[] { DASH, GAP, DASH, GAP, DOT, GAP, DASH },
+        /* R */ new long[] { DOT, GAP, DASH, GAP, DOT },
+        /* S */ new long[] { DOT, GAP, DOT, GAP, DOT },
+        /* T */ new long[] { DASH },
+        /* U */ new long[] { DOT, GAP, DOT, GAP, DASH },
+        /* V */ new long[] { DOT, GAP, DOT, GAP, DASH },
+        /* W */ new long[] { DOT, GAP, DASH, GAP, DASH },
+        /* X */ new long[] { DASH, GAP, DOT, GAP, DOT, GAP, DASH },
+        /* Y */ new long[] { DASH, GAP, DOT, GAP, DASH, GAP, DASH },
+        /* Z */ new long[] { DASH, GAP, DASH, GAP, DOT, GAP, DOT },
+    };
+
+    /** The characters from '0' to '9' */
+    private static final long[][] NUMBERS = new long[][] {
+        /* 0 */ new long[] { DASH, GAP, DASH, GAP, DASH, GAP, DASH, GAP, DASH },
+        /* 1 */ new long[] { DOT, GAP, DASH, GAP, DASH, GAP, DASH, GAP, DASH },
+        /* 2 */ new long[] { DOT, GAP, DOT, GAP, DASH, GAP, DASH, GAP, DASH },
+        /* 3 */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DASH, GAP, DASH },
+        /* 4 */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DOT, GAP, DASH },
+        /* 5 */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DOT, GAP, DOT },
+        /* 6 */ new long[] { DASH, GAP, DOT, GAP, DOT, GAP, DOT, GAP, DOT },
+        /* 7 */ new long[] { DASH, GAP, DASH, GAP, DOT, GAP, DOT, GAP, DOT },
+        /* 8 */ new long[] { DASH, GAP, DASH, GAP, DASH, GAP, DOT, GAP, DOT },
+        /* 9 */ new long[] { DASH, GAP, DASH, GAP, DASH, GAP, DASH, GAP, DOT },
+    };
+
+    private static final long[] ERROR_GAP = new long[] { GAP };
+
+    /** Return the pattern data for a given character */
+    static long[] pattern(char c) {
+        if (c >= 'A' && c <= 'Z') {
+            return LETTERS[c - 'A'];
+        }
+        if (c >= 'a' && c <= 'z') {
+            return LETTERS[c - 'a'];
+        }
+        else if (c >= '0' && c <= '9') {
+            return NUMBERS[c - '0'];
+        }
+        else {
+            return ERROR_GAP;
+        }
+    }
+
+    static long[] pattern(String str) {
+        boolean lastWasWhitespace;
+        int strlen = str.length();
+
+        // Calculate how long our array needs to be.
+        int len = 1;
+        lastWasWhitespace = true;
+        for (int i=0; i<strlen; i++) {
+            char c = str.charAt(i);
+            if (Character.isWhitespace(c)) {
+                if (!lastWasWhitespace) {
+                    len++;
+                    lastWasWhitespace = true;
+                }
+            } else {
+                if (!lastWasWhitespace) {
+                    len++;
+                }
+                lastWasWhitespace = false;
+                len += pattern(c).length;
+            }
+        }
+
+        // Generate the pattern array.  Note that we put an extra element of 0
+        // in at the beginning, because the pattern always starts with the pause,
+        // not with the vibration.
+        long[] result = new long[len+1];
+        result[0] = 0;
+        int pos = 1;
+        lastWasWhitespace = true;
+        for (int i=0; i<strlen; i++) {
+            char c = str.charAt(i);
+            if (Character.isWhitespace(c)) {
+                if (!lastWasWhitespace) {
+                    result[pos] = WORD_GAP;
+                    pos++;
+                    lastWasWhitespace = true;
+                }
+            } else {
+                if (!lastWasWhitespace) {
+                    result[pos] = LETTER_GAP;
+                    pos++;
+                }
+                lastWasWhitespace = false;
+                long[] letter = pattern(c);
+                System.arraycopy(letter, 0, result, pos, letter.length);
+                pos += letter.length;
+            }
+        }
+        return result;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/os/Sensors.java b/samples/ApiDemos/src/com/example/android/apis/os/Sensors.java
new file mode 100644
index 0000000..910961d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/os/Sensors.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.os;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.hardware.SensorManager;
+import android.hardware.SensorListener;
+import android.util.Log;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.RectF;
+
+/**
+ * <h3>Application that displays the values of the acceleration sensor graphically.</h3>
+
+<p>This demonstrates the {@link android.hardware.SensorManager android.hardware.SensorManager} class.
+
+<h4>Demo</h4>
+OS / Sensors
+ 
+<h4>Source files</h4>
+ * <table class="LinkTable">
+ *         <tr>
+ *             <td >src/com.example.android.apis/os/Sensors.java</td>
+ *             <td >Sensors</td>
+ *         </tr>
+ * </table> 
+ */
+public class Sensors extends Activity {
+    /** Tag string for our debug logs */
+    private static final String TAG = "Sensors";
+
+    private SensorManager mSensorManager;
+    private GraphView mGraphView;
+
+    private class GraphView extends View implements SensorListener
+    {
+        private Bitmap  mBitmap;
+        private Paint   mPaint = new Paint();
+        private Canvas  mCanvas = new Canvas();
+        private Path    mPath = new Path();
+        private RectF   mRect = new RectF();
+        private float   mLastValues[] = new float[3*2];
+        private float   mOrientationValues[] = new float[3];
+        private int     mColors[] = new int[3*2];
+        private float   mLastX;
+        private float   mScale[] = new float[2];
+        private float   mYOffset;
+        private float   mMaxX;
+        private float   mSpeed = 1.0f;
+        private float   mWidth;
+        private float   mHeight;
+        
+        public GraphView(Context context) {
+            super(context);
+            mColors[0] = Color.argb(192, 255, 64, 64);
+            mColors[1] = Color.argb(192, 64, 128, 64);
+            mColors[2] = Color.argb(192, 64, 64, 255);
+            mColors[3] = Color.argb(192, 64, 255, 255);
+            mColors[4] = Color.argb(192, 128, 64, 128);
+            mColors[5] = Color.argb(192, 255, 255, 64);
+
+            mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
+            mRect.set(-0.5f, -0.5f, 0.5f, 0.5f);
+            mPath.arcTo(mRect, 0, 180);
+        }
+        
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
+            mCanvas.setBitmap(mBitmap);
+            mCanvas.drawColor(0xFFFFFFFF);
+            mYOffset = h * 0.5f;
+            mScale[0] = - (h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
+            mScale[1] = - (h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
+            mWidth = w;
+            mHeight = h;
+            if (mWidth < mHeight) {
+                mMaxX = w;
+            } else {
+                mMaxX = w-50;
+            }
+            mLastX = mMaxX;
+            super.onSizeChanged(w, h, oldw, oldh);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            synchronized (this) {
+                if (mBitmap != null) {
+                    final Paint paint = mPaint;
+                    final Path path = mPath;
+                    final int outer = 0xFFC0C0C0;
+                    final int inner = 0xFFff7010;
+
+                    if (mLastX >= mMaxX) {
+                        mLastX = 0;
+                        final Canvas cavas = mCanvas;
+                        final float yoffset = mYOffset;
+                        final float maxx = mMaxX;
+                        final float oneG = SensorManager.STANDARD_GRAVITY * mScale[0];
+                        paint.setColor(0xFFAAAAAA);
+                        cavas.drawColor(0xFFFFFFFF);
+                        cavas.drawLine(0, yoffset,      maxx, yoffset,      paint);
+                        cavas.drawLine(0, yoffset+oneG, maxx, yoffset+oneG, paint);
+                        cavas.drawLine(0, yoffset-oneG, maxx, yoffset-oneG, paint);
+                    }
+                    canvas.drawBitmap(mBitmap, 0, 0, null);
+
+                    float[] values = mOrientationValues;
+                    if (mWidth < mHeight) {
+                        float w0 = mWidth * 0.333333f;
+                        float w  = w0 - 32;
+                        float x = w0*0.5f;
+                        for (int i=0 ; i<3 ; i++) {
+                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
+                            canvas.translate(x, w*0.5f + 4.0f);
+                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
+                            paint.setColor(outer);
+                            canvas.scale(w, w);
+                            canvas.drawOval(mRect, paint);
+                            canvas.restore();
+                            canvas.scale(w-5, w-5);
+                            paint.setColor(inner);
+                            canvas.rotate(-values[i]);
+                            canvas.drawPath(path, paint);
+                            canvas.restore();
+                            x += w0;
+                        }
+                    } else {
+                        float h0 = mHeight * 0.333333f;
+                        float h  = h0 - 32;
+                        float y = h0*0.5f;
+                        for (int i=0 ; i<3 ; i++) {
+                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
+                            canvas.translate(mWidth - (h*0.5f + 4.0f), y);
+                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
+                            paint.setColor(outer);
+                            canvas.scale(h, h);
+                            canvas.drawOval(mRect, paint);
+                            canvas.restore();
+                            canvas.scale(h-5, h-5);
+                            paint.setColor(inner);
+                            canvas.rotate(-values[i]);
+                            canvas.drawPath(path, paint);
+                            canvas.restore();
+                            y += h0;
+                        }
+                    }
+
+                }
+            }
+        }
+
+        public void onSensorChanged(int sensor, float[] values) {
+            //Log.d(TAG, "sensor: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: " + values[2]);
+            synchronized (this) {
+                if (mBitmap != null) {
+                    final Canvas canvas = mCanvas;
+                    final Paint paint = mPaint;
+                    if (sensor == SensorManager.SENSOR_ORIENTATION) {
+                        for (int i=0 ; i<3 ; i++) {
+                            mOrientationValues[i] = values[i];
+                        }
+                    } else {
+                        float deltaX = mSpeed;
+                        float newX = mLastX + deltaX;
+
+                        int j = (sensor == SensorManager.SENSOR_MAGNETIC_FIELD) ? 1 : 0;
+                        for (int i=0 ; i<3 ; i++) {
+                            int k = i+j*3;
+                            final float v = mYOffset + values[i] * mScale[j];
+                            paint.setColor(mColors[k]);
+                            canvas.drawLine(mLastX, mLastValues[k], newX, v, paint);
+                            mLastValues[k] = v;
+                        }
+                        if (sensor == SensorManager.SENSOR_MAGNETIC_FIELD)
+                            mLastX += mSpeed;
+                    }
+                    invalidate();
+                }
+            }
+        }
+
+        public void onAccuracyChanged(int sensor, int accuracy) {
+            // TODO Auto-generated method stub
+            
+        }
+    }
+    
+    /**
+     * Initialization of the Activity after it is first created.  Must at least
+     * call {@link android.app.Activity#setContentView setContentView()} to
+     * describe what is to be displayed in the screen.
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
+        mGraphView = new GraphView(this);
+        setContentView(mGraphView);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mSensorManager.registerListener(mGraphView, 
+                SensorManager.SENSOR_ACCELEROMETER | 
+                SensorManager.SENSOR_MAGNETIC_FIELD | 
+                SensorManager.SENSOR_ORIENTATION,
+                SensorManager.SENSOR_DELAY_FASTEST);
+    }
+    
+    @Override
+    protected void onStop() {
+        mSensorManager.unregisterListener(mGraphView);
+        super.onStop();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/text/Link.java b/samples/ApiDemos/src/com/example/android/apis/text/Link.java
new file mode 100644
index 0000000..b569d19
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/text/Link.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.text;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.text.style.StyleSpan;
+import android.text.style.URLSpan;
+import android.widget.TextView;
+
+public class Link extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.link);
+
+        // text1 shows the android:autoLink property, which
+        // automatically linkifies things like URLs and phone numbers
+        // found in the text.  No java code is needed to make this
+        // work.
+
+        // text2 has links specified by putting <a> tags in the string
+        // resource.  By default these links will appear but not
+        // respond to user input.  To make them active, you need to
+        // call setMovementMethod() on the TextView object.
+
+        TextView t2 = (TextView) findViewById(R.id.text2);
+        t2.setMovementMethod(LinkMovementMethod.getInstance());
+
+        // text3 shows creating text with links from HTML in the Java
+        // code, rather than from a string resource.  Note that for a
+        // fixed string, using a (localizable) resource as shown above
+        // is usually a better way to go; this example is intended to
+        // illustrate how you might display text that came from a
+        // dynamic source (eg, the network).
+
+        TextView t3 = (TextView) findViewById(R.id.text3);
+        t3.setText(
+            Html.fromHtml(
+                "<b>text3:</b>  Text with a " +
+                "<a href=\"http://www.google.com\">link</a> " +
+                "created in the Java source code using HTML."));
+        t3.setMovementMethod(LinkMovementMethod.getInstance());
+
+        // text4 illustrates constructing a styled string containing a
+        // link without using HTML at all.  Again, for a fixed string
+        // you should probably be using a string resource, not a
+        // hardcoded value.
+
+        SpannableString ss = new SpannableString(
+            "text4: Click here to dial the phone.");
+
+        ss.setSpan(new StyleSpan(Typeface.BOLD), 0, 6,
+                   Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        ss.setSpan(new URLSpan("tel:4155551212"), 13, 17,
+                   Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextView t4 = (TextView) findViewById(R.id.text4);
+        t4.setText(ss);
+        t4.setMovementMethod(LinkMovementMethod.getInstance());
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/text/LogTextBox.java b/samples/ApiDemos/src/com/example/android/apis/text/LogTextBox.java
new file mode 100644
index 0000000..c78b54b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/text/LogTextBox.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.text;
+
+import android.widget.TextView;
+import android.content.Context;
+import android.text.method.ScrollingMovementMethod;
+import android.text.method.MovementMethod;
+import android.text.method.KeyListener;
+import android.text.method.TransformationMethod;
+import android.text.Editable;
+import android.util.AttributeSet;
+
+import java.util.Map;
+
+/**
+ * This is a TextView that is Editable and by default scrollable,
+ * like EditText without a cursor.
+ *
+ * <p>
+ * <b>XML attributes</b>
+ * <p>
+ * See
+ * {@link android.R.styleable#TextView TextView Attributes},
+ * {@link android.R.styleable#View View Attributes}
+ */
+public class LogTextBox extends TextView {
+    public LogTextBox(Context context) {
+        this(context, null);
+    }
+
+    public LogTextBox(Context context, AttributeSet attrs) {
+        this(context, attrs, android.R.attr.textViewStyle);
+    }
+
+    public LogTextBox(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected MovementMethod getDefaultMovementMethod() {
+        return ScrollingMovementMethod.getInstance();
+    }
+
+    @Override
+    public Editable getText() {
+        return (Editable) super.getText();
+    }
+
+    @Override
+    public void setText(CharSequence text, BufferType type) {
+        super.setText(text, BufferType.EDITABLE);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/text/LogTextBox1.java b/samples/ApiDemos/src/com/example/android/apis/text/LogTextBox1.java
new file mode 100644
index 0000000..1813629
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/text/LogTextBox1.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.text;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Using a LogTextBox to display a scrollable text area
+ * to which text is appended.
+ *
+ */
+public class LogTextBox1 extends Activity {
+    
+    private LogTextBox mText;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.log_text_box_1);
+        
+        mText = (LogTextBox) findViewById(R.id.text);
+        
+        Button addButton = (Button) findViewById(R.id.add);
+        addButton.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                mText.append("This is a test\n");
+            } });
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/text/Marquee.java b/samples/ApiDemos/src/com/example/android/apis/text/Marquee.java
new file mode 100644
index 0000000..ba82ed6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/text/Marquee.java
@@ -0,0 +1,31 @@
+/* 
+ * Copyright (C) 2007 Google Inc.
+ *
+ * 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.text;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Marquee extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.marquee);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/text/_index.html b/samples/ApiDemos/src/com/example/android/apis/text/_index.html
new file mode 100644
index 0000000..ee1020b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/text/_index.html
@@ -0,0 +1,6 @@
+<dl>
+  <dt><a href="Link.html">Linkify</a></dt>
+  <dd>Demonstrates the {@link android.text.util.Linkify Linkify} class, which converts URLs in a block of text into hyperlinks. </dd>
+</dl>
+
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation1.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation1.java
new file mode 100644
index 0000000..73563f3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation1.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+public class Animation1 extends Activity implements View.OnClickListener {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_1);
+
+        View loginButton = findViewById(R.id.login);
+        loginButton.setOnClickListener(this);
+    }
+
+    public void onClick(View v) {
+        Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
+        findViewById(R.id.pw).startAnimation(shake);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
new file mode 100644
index 0000000..b2236aa
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+import android.widget.ViewFlipper;
+
+
+public class Animation2 extends Activity implements
+        AdapterView.OnItemSelectedListener {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_2);
+
+        mFlipper = ((ViewFlipper) this.findViewById(R.id.flipper));
+        mFlipper.startFlipping();
+
+        Spinner s = (Spinner) findViewById(R.id.spinner);
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, mStrings);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s.setAdapter(adapter);
+        s.setOnItemSelectedListener(this);
+    }
+
+    public void onItemSelected(AdapterView parent, View v, int position, long id) {
+        switch (position) {
+
+        case 0:
+            mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
+                    R.anim.push_up_in));
+            mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
+                    R.anim.push_up_out));
+            break;
+        case 1:
+            mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
+                    R.anim.push_left_in));
+            mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
+                    R.anim.push_left_out));
+            break;
+        case 2:
+            mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
+                    android.R.anim.fade_in));
+            mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
+                    android.R.anim.fade_out));
+            break;
+        default:
+            mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
+                    R.anim.hyperspace_in));
+            mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
+                    R.anim.hyperspace_out));
+            break;
+        }
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+    }
+
+    private String[] mStrings = {
+            "Push up", "Push left", "Cross fade", "Hyperspace"};
+
+    private ViewFlipper mFlipper;
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
new file mode 100644
index 0000000..f4274e5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.Spinner;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.os.Bundle;
+import android.view.View;
+
+
+public class AutoComplete1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.autocomplete_1);
+
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_dropdown_item_1line, COUNTRIES);
+        AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit);
+        textView.setAdapter(adapter);
+    }
+
+    static final String[] COUNTRIES = new String[] {
+	"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+	"Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+	"Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+	"Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+	"Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+	"Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
+	"British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
+	"Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+	"Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+	"Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+	"Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+	"Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+	"East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+	"Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+	"Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+	"French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+	"Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+	"Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+	"Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+	"Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+	"Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+	"Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+	"Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+	"Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+	"Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+	"Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+	"Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+	"Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+	"Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+	"Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+	"Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+	"Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+	"Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+	"Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+	"Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+	"The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+	"Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+	"Ukraine", "United Arab Emirates", "United Kingdom",
+	"United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+	"Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+	"Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete2.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete2.java
new file mode 100644
index 0000000..2dcfc12
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete2.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+
+
+public class AutoComplete2 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.autocomplete_2);
+
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_dropdown_item_1line,
+                AutoComplete1.COUNTRIES);
+        AutoCompleteTextView textView = (AutoCompleteTextView)
+                findViewById(R.id.edit);
+        textView.setAdapter(adapter);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete3.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete3.java
new file mode 100644
index 0000000..bb9408f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete3.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+
+
+public class AutoComplete3 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.autocomplete_3);
+
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_dropdown_item_1line,
+                AutoComplete1.COUNTRIES);
+        AutoCompleteTextView textView = (AutoCompleteTextView)
+                findViewById(R.id.edit);
+        textView.setAdapter(adapter);
+        textView = (AutoCompleteTextView) findViewById(R.id.edit2);
+        textView.setAdapter(adapter);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
new file mode 100644
index 0000000..c6fa08b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Contacts;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AutoCompleteTextView;
+import android.widget.CursorAdapter;
+import android.widget.Filterable;
+import android.widget.TextView;
+
+public class AutoComplete4 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.autocomplete_4);
+
+        ContentResolver content = getContentResolver();
+        Cursor cursor = content.query(Contacts.People.CONTENT_URI,
+                PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
+        ContactListAdapter adapter = new ContactListAdapter(this, cursor);
+
+        AutoCompleteTextView textView = (AutoCompleteTextView)
+                findViewById(R.id.edit);
+        textView.setAdapter(adapter);
+    }
+
+    // XXX compiler bug in javac 1.5.0_07-164, we need to implement Filterable
+    // to make compilation work
+    public static class ContactListAdapter extends CursorAdapter implements Filterable {
+        public ContactListAdapter(Context context, Cursor c) {
+            super(context, c);
+            mContent = context.getContentResolver();
+        }
+
+        @Override
+        public View newView(Context context, Cursor cursor, ViewGroup parent) {
+            final LayoutInflater inflater = LayoutInflater.from(context);
+            final TextView view = (TextView) inflater.inflate(
+                    android.R.layout.simple_dropdown_item_1line, parent, false);
+            view.setText(cursor.getString(5));
+            return view;
+        }
+
+        @Override
+        public void bindView(View view, Context context, Cursor cursor) {
+            ((TextView) view).setText(cursor.getString(5));
+        }
+
+        @Override
+        public String convertToString(Cursor cursor) {
+            return cursor.getString(5);
+        }
+
+        @Override
+        public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
+            if (getFilterQueryProvider() != null) {
+                return getFilterQueryProvider().runQuery(constraint);
+            }
+
+            StringBuilder buffer = null;
+            String[] args = null;
+            if (constraint != null) {
+                buffer = new StringBuilder();
+                buffer.append("UPPER(");
+                buffer.append(Contacts.ContactMethods.NAME);
+                buffer.append(") GLOB ?");
+                args = new String[] { constraint.toString().toUpperCase() + "*" };
+            }
+
+            return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
+                    buffer == null ? null : buffer.toString(), args,
+                    Contacts.People.DEFAULT_SORT_ORDER);
+        }
+
+        private ContentResolver mContent;        
+    }
+
+    private static final String[] PEOPLE_PROJECTION = new String[] {
+        Contacts.People._ID,
+        Contacts.People.PRIMARY_PHONE_ID,
+        Contacts.People.TYPE,
+        Contacts.People.NUMBER,
+        Contacts.People.LABEL,
+        Contacts.People.NAME,
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
new file mode 100644
index 0000000..7406da4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Contacts;
+import android.widget.AutoCompleteTextView;
+
+public class AutoComplete5 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.autocomplete_5);
+
+        ContentResolver content = getContentResolver();
+        Cursor cursor = content.query(Contacts.People.CONTENT_URI,
+                PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
+        AutoComplete4.ContactListAdapter adapter =
+                new AutoComplete4.ContactListAdapter(this, cursor);
+
+        AutoCompleteTextView textView = (AutoCompleteTextView)
+                findViewById(R.id.edit);
+        textView.setAdapter(adapter);
+    }
+
+    private static final String[] PEOPLE_PROJECTION = new String[] {
+        Contacts.People._ID,
+        Contacts.People.PRIMARY_PHONE_ID,
+        Contacts.People.TYPE,
+        Contacts.People.NUMBER,
+        Contacts.People.LABEL,
+        Contacts.People.NAME
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
new file mode 100644
index 0000000..3573bfb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.Spinner;
+import android.widget.ArrayAdapter;
+import android.widget.MultiAutoCompleteTextView;
+import android.os.Bundle;
+import android.view.View;
+
+
+public class AutoComplete6 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.autocomplete_6);
+
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_dropdown_item_1line, COUNTRIES);
+        MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.edit);
+        textView.setAdapter(adapter);
+        textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
+    }
+
+    static final String[] COUNTRIES = new String[] {
+    "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+    "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+    "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+    "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+    "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+    "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
+    "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
+    "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+    "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+    "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+    "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+    "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+    "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+    "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+    "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+    "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+    "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+    "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+    "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+    "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+    "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+    "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+    "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+    "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+    "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+    "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+    "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+    "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+    "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+    "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+    "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+    "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+    "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+    "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+    "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+    "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+    "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+    "Ukraine", "United Arab Emirates", "United Kingdom",
+    "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+    "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+    "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Baseline1.java b/samples/ApiDemos/src/com/example/android/apis/view/Baseline1.java
new file mode 100644
index 0000000..c77b71f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Baseline1.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Baseline alignment in LinearLayout.
+ */
+public class Baseline1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.baseline_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Baseline2.java b/samples/ApiDemos/src/com/example/android/apis/view/Baseline2.java
new file mode 100644
index 0000000..7189fe8
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Baseline2.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Baseline alignment in LinearLayout with a BOTTOM gravity.
+ */
+public class Baseline2 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.baseline_2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Baseline3.java b/samples/ApiDemos/src/com/example/android/apis/view/Baseline3.java
new file mode 100644
index 0000000..9261c5c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Baseline3.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Baseline alignement in LinearLayout with a center_vertical gravity. This sample shows that
+ * using a center_vertical gravity disables baseline alignment.
+ */
+public class Baseline3 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.baseline_3);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Baseline4.java b/samples/ApiDemos/src/com/example/android/apis/view/Baseline4.java
new file mode 100644
index 0000000..bedfde7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Baseline4.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Baseline alignment in LinearLayout with mixed gravities.
+ */
+public class Baseline4 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.baseline_4);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Baseline6.java b/samples/ApiDemos/src/com/example/android/apis/view/Baseline6.java
new file mode 100644
index 0000000..e96e10a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Baseline6.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Baseline alignment in RelativeLayout.
+ */
+public class Baseline6 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.baseline_6);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Baseline7.java b/samples/ApiDemos/src/com/example/android/apis/view/Baseline7.java
new file mode 100644
index 0000000..1795e7d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Baseline7.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Baseline alignment in RelativeLayout with various font weights.
+ */
+public class Baseline7 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.baseline_7);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested1.java b/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested1.java
new file mode 100644
index 0000000..d60e702
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested1.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Baseline alignment includes elements within nested vertical
+ * {@link android.widget.LinearLayout}s.
+ */
+public class BaselineNested1 extends Activity {
+
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.baseline_nested_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested2.java b/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested2.java
new file mode 100644
index 0000000..32574d7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested2.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Baseline alignment includes an element within a nested horizontal
+ * {@link android.widget.LinearLayout}.
+ */
+public class BaselineNested2 extends Activity {
+
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.baseline_nested_2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested3.java b/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested3.java
new file mode 100644
index 0000000..3377041
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested3.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Baseline alignment includes a {@link android.widget.LinearLayout}
+ * within another {@link android.widget.LinearLayout}.
+ */
+public class BaselineNested3 extends Activity {
+
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.baseline_nested_3);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java b/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
new file mode 100644
index 0000000..e2f8cc8
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Spinner;
+import android.widget.ArrayAdapter;
+
+
+/**
+ * A gallery of the different styles of buttons.
+ */
+public class Buttons1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.buttons_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ChronometerDemo.java b/samples/ApiDemos/src/com/example/android/apis/view/ChronometerDemo.java
new file mode 100644
index 0000000..752adc6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ChronometerDemo.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Chronometer;
+
+public class ChronometerDemo extends Activity {
+    Chronometer mChronometer;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.chronometer);
+
+        Button button;
+
+        mChronometer = (Chronometer) findViewById(R.id.chronometer);
+
+        // Watch for button clicks.
+        button = (Button) findViewById(R.id.start);
+        button.setOnClickListener(mStartListener);
+
+        button = (Button) findViewById(R.id.stop);
+        button.setOnClickListener(mStopListener);
+
+        button = (Button) findViewById(R.id.reset);
+        button.setOnClickListener(mResetListener);
+
+        button = (Button) findViewById(R.id.set_format);
+        button.setOnClickListener(mSetFormatListener);
+
+        button = (Button) findViewById(R.id.clear_format);
+        button.setOnClickListener(mClearFormatListener);
+    }
+
+    View.OnClickListener mStartListener = new OnClickListener() {
+        public void onClick(View v) {
+            mChronometer.start();
+        }
+    };
+
+    View.OnClickListener mStopListener = new OnClickListener() {
+        public void onClick(View v) {
+            mChronometer.stop();
+        }
+    };
+
+    View.OnClickListener mResetListener = new OnClickListener() {
+        public void onClick(View v) {
+            mChronometer.setBase(SystemClock.elapsedRealtime());
+        }
+    };
+
+    View.OnClickListener mSetFormatListener = new OnClickListener() {
+        public void onClick(View v) {
+            mChronometer.setFormat("Formatted time (%s)");
+        }
+    };
+
+    View.OnClickListener mClearFormatListener = new OnClickListener() {
+        public void onClick(View v) {
+            mChronometer.setFormat(null);
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java
new file mode 100644
index 0000000..e2d348f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls1.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Spinner;
+import android.widget.ArrayAdapter;
+
+
+/**
+ * A gallery of basic controls: Button, EditText, RadioButton, Checkbox,
+ * Spinner. This example uses the light theme.
+ */
+public class Controls1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.controls_1);
+
+        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, mStrings);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s1.setAdapter(adapter);
+    }
+
+    private static final String[] mStrings = {
+        "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java
new file mode 100644
index 0000000..4f4024b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls2.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Spinner;
+import android.widget.ArrayAdapter;
+
+
+/**
+ * A gallery of basic controls: Button, EditText, RadioButton, Checkbox,
+ * Spinner. This example uses the default theme.
+ */
+public class Controls2 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.controls_1);
+
+        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, mStrings);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s1.setAdapter(adapter);
+    }
+
+    private static final String[] mStrings = {
+	    "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/CustomView1.java b/samples/ApiDemos/src/com/example/android/apis/view/CustomView1.java
new file mode 100644
index 0000000..314738e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/CustomView1.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates creating a Screen that uses custom views. This example uses
+ * {@link com.example.android.apis.view.LabelView}, which is defined in
+ * SDK/src/com/example/android/apis/view/LabelView.java.
+ * 
+ */
+public class CustomView1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.custom_view_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets1.java b/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets1.java
new file mode 100644
index 0000000..f0b1d22
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets1.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.DatePickerDialog;
+import android.app.TimePickerDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.DatePicker;
+import android.widget.TimePicker;
+import android.view.View;
+
+import java.util.Calendar;
+
+/**
+ * Basic example of using date and time widgets, including
+ * {@link android.app.TimePickerDialog} and {@link android.widget.DatePicker}.
+ *
+ * Also provides a good example of using {@link Activity#onCreateDialog},
+ * {@link Activity#onPrepareDialog} and {@link Activity#showDialog} to have the
+ * activity automatically save and restore the state of the dialogs.
+ */
+public class DateWidgets1 extends Activity {
+
+    // where we display the selected date and time
+    private TextView mDateDisplay;
+
+    // date and time
+    private int mYear;
+    private int mMonth;
+    private int mDay;
+    private int mHour;
+    private int mMinute;
+
+    static final int TIME_DIALOG_ID = 0;
+    static final int DATE_DIALOG_ID = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.date_widgets_example_1);
+
+        mDateDisplay = (TextView) findViewById(R.id.dateDisplay);
+
+        Button pickDate = (Button) findViewById(R.id.pickDate);
+        pickDate.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                showDialog(DATE_DIALOG_ID);
+            }
+        });
+
+        Button pickTime = (Button) findViewById(R.id.pickTime);
+        pickTime.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                showDialog(TIME_DIALOG_ID);
+            }
+        });
+
+        final Calendar c = Calendar.getInstance();
+        mYear = c.get(Calendar.YEAR);
+        mMonth = c.get(Calendar.MONTH);
+        mDay = c.get(Calendar.DAY_OF_MONTH);
+        mHour = c.get(Calendar.HOUR_OF_DAY);
+        mMinute = c.get(Calendar.MINUTE);
+
+        updateDisplay();
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case TIME_DIALOG_ID:
+                return new TimePickerDialog(this,
+                        mTimeSetListener, mHour, mMinute, false);
+            case DATE_DIALOG_ID:
+                return new DatePickerDialog(this,
+                            mDateSetListener,
+                            mYear, mMonth, mDay);
+        }
+        return null;
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        switch (id) {
+            case TIME_DIALOG_ID:
+                ((TimePickerDialog) dialog).updateTime(mHour, mMinute);
+                break;
+            case DATE_DIALOG_ID:
+                ((DatePickerDialog) dialog).updateDate(mYear, mMonth, mDay);
+                break;
+        }
+    }    
+
+    private void updateDisplay() {
+        mDateDisplay.setText(
+            new StringBuilder()
+                    // Month is 0 based so add 1
+                    .append(mMonth + 1).append("-")
+                    .append(mDay).append("-")
+                    .append(mYear).append(" ")
+                    .append(pad(mHour)).append(":")
+                    .append(pad(mMinute)));
+    }
+
+    private DatePickerDialog.OnDateSetListener mDateSetListener =
+            new DatePickerDialog.OnDateSetListener() {
+
+                public void onDateSet(DatePicker view, int year, int monthOfYear,
+                        int dayOfMonth) {
+                    mYear = year;
+                    mMonth = monthOfYear;
+                    mDay = dayOfMonth;
+                    updateDisplay();
+                }
+            };
+
+    private TimePickerDialog.OnTimeSetListener mTimeSetListener =
+            new TimePickerDialog.OnTimeSetListener() {
+
+                public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+                    mHour = hourOfDay;
+                    mMinute = minute;
+                    updateDisplay();
+                }
+            };
+
+    private static String pad(int c) {
+        if (c >= 10)
+            return String.valueOf(c);
+        else
+            return "0" + String.valueOf(c);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets2.java b/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets2.java
new file mode 100644
index 0000000..15123a8
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets2.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.widget.TimePicker;
+import android.os.Bundle;
+
+public class DateWidgets2 extends Activity {
+
+    // where we display the selected date and time
+    private TextView mTimeDisplay;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.date_widgets_example_2);
+
+        TimePicker timePicker = (TimePicker) findViewById(R.id.timePicker);
+        timePicker.setCurrentHour(12);
+        timePicker.setCurrentMinute(15);
+
+        mTimeDisplay = (TextView) findViewById(R.id.dateDisplay);
+
+        updateDisplay(12, 15);
+
+        timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
+
+            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
+                updateDisplay(hourOfDay, minute);
+            }
+        });
+    }
+
+    private void updateDisplay(int hourOfDay, int minute) {
+        mTimeDisplay.setText(
+                    new StringBuilder()
+                    .append(pad(hourOfDay)).append(":")
+                    .append(pad(minute)));
+    }
+
+    private static String pad(int c) {
+        if (c >= 10)
+            return String.valueOf(c);
+        else
+            return "0" + String.valueOf(c);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList1.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList1.java
new file mode 100644
index 0000000..944db64
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList1.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ExpandableListActivity;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.Gravity;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.AbsListView;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
+
+import com.example.android.apis.R;
+
+/**
+ * Demonstrates expandable lists using a custom {@link ExpandableListAdapter}
+ * from {@link BaseExpandableListAdapter}.
+ */
+public class ExpandableList1 extends ExpandableListActivity {
+
+    ExpandableListAdapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Set up our adapter
+        mAdapter = new MyExpandableListAdapter();
+        setListAdapter(mAdapter);
+        registerForContextMenu(getExpandableListView());
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        menu.setHeaderTitle("Sample menu");
+        menu.add(0, 0, 0, R.string.expandable_list_sample_action);
+    }
+    
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
+
+        String title = ((TextView) info.targetView).getText().toString();
+        
+        int type = ExpandableListView.getPackedPositionType(info.packedPosition);
+        if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
+            int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); 
+            int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); 
+            Toast.makeText(this, title + ": Child " + childPos + " clicked in group " + groupPos,
+                    Toast.LENGTH_SHORT).show();
+            return true;
+        } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
+            int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); 
+            Toast.makeText(this, title + ": Group " + groupPos + " clicked", Toast.LENGTH_SHORT).show();
+            return true;
+        }
+        
+        return false;
+    }
+
+    /**
+     * A simple adapter which maintains an ArrayList of photo resource Ids. 
+     * Each photo is displayed as an image. This adapter supports clearing the
+     * list of photos and adding a new photo.
+     *
+     */
+    public class MyExpandableListAdapter extends BaseExpandableListAdapter {
+        // Sample data set.  children[i] contains the children (String[]) for groups[i].
+        private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" };
+        private String[][] children = {
+                { "Arnold", "Barry", "Chuck", "David" },
+                { "Ace", "Bandit", "Cha-Cha", "Deuce" },
+                { "Fluffy", "Snuggles" },
+                { "Goldy", "Bubbles" }
+        };
+        
+        public Object getChild(int groupPosition, int childPosition) {
+            return children[groupPosition][childPosition];
+        }
+
+        public long getChildId(int groupPosition, int childPosition) {
+            return childPosition;
+        }
+
+        public int getChildrenCount(int groupPosition) {
+            return children[groupPosition].length;
+        }
+
+        public TextView getGenericView() {
+            // Layout parameters for the ExpandableListView
+            AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
+                    ViewGroup.LayoutParams.FILL_PARENT, 64);
+
+            TextView textView = new TextView(ExpandableList1.this);
+            textView.setLayoutParams(lp);
+            // Center the text vertically
+            textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
+            // Set the text starting position
+            textView.setPadding(36, 0, 0, 0);
+            return textView;
+        }
+        
+        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+                View convertView, ViewGroup parent) {
+            TextView textView = getGenericView();
+            textView.setText(getChild(groupPosition, childPosition).toString());
+            return textView;
+        }
+
+        public Object getGroup(int groupPosition) {
+            return groups[groupPosition];
+        }
+
+        public int getGroupCount() {
+            return groups.length;
+        }
+
+        public long getGroupId(int groupPosition) {
+            return groupPosition;
+        }
+
+        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+                ViewGroup parent) {
+            TextView textView = getGenericView();
+            textView.setText(getGroup(groupPosition).toString());
+            return textView;
+        }
+
+        public boolean isChildSelectable(int groupPosition, int childPosition) {
+            return true;
+        }
+
+        public boolean hasStableIds() {
+            return true;
+        }
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
new file mode 100644
index 0000000..5784122
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ExpandableListActivity;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Contacts.People;
+import android.widget.ExpandableListAdapter;
+import android.widget.SimpleCursorTreeAdapter;
+
+
+/**
+ * Demonstrates expandable lists backed by Cursors
+ */
+public class ExpandableList2 extends ExpandableListActivity {
+    private int mGroupIdColumnIndex; 
+    
+    private String mPhoneNumberProjection[] = new String[] {
+            People.Phones._ID, People.Phones.NUMBER
+    };
+
+    
+    private ExpandableListAdapter mAdapter;
+    
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Query for people
+        Cursor groupCursor = managedQuery(People.CONTENT_URI,
+                new String[] {People._ID, People.NAME}, null, null, null);
+
+        // Cache the ID column index
+        mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow(People._ID);
+
+        // Set up our adapter
+        mAdapter = new MyExpandableListAdapter(groupCursor,
+                this,
+                android.R.layout.simple_expandable_list_item_1,
+                android.R.layout.simple_expandable_list_item_1,
+                new String[] {People.NAME}, // Name for group layouts
+                new int[] {android.R.id.text1},
+                new String[] {People.NUMBER}, // Number for child layouts
+                new int[] {android.R.id.text1});
+        setListAdapter(mAdapter);
+    }
+
+    public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
+
+        public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout,
+                int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
+                int[] childrenTo) {
+            super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
+                    childrenTo);
+        }
+
+        @Override
+        protected Cursor getChildrenCursor(Cursor groupCursor) {
+            // Given the group, we return a cursor for all the children within that group 
+
+            // Return a cursor that points to this contact's phone numbers
+            Uri.Builder builder = People.CONTENT_URI.buildUpon();
+            ContentUris.appendId(builder, groupCursor.getLong(mGroupIdColumnIndex));
+            builder.appendEncodedPath(People.Phones.CONTENT_DIRECTORY);
+            Uri phoneNumbersUri = builder.build();
+
+            // The returned Cursor MUST be managed by us, so we use Activity's helper
+            // functionality to manage it for us.
+            return managedQuery(phoneNumbersUri, mPhoneNumberProjection, null, null, null);
+        }
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.java
new file mode 100644
index 0000000..3a298b3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ExpandableListActivity;
+import android.os.Bundle;
+import android.widget.ExpandableListAdapter;
+import android.widget.SimpleExpandableListAdapter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Demonstrates expandable lists backed by a Simple Map-based adapter
+ */
+public class ExpandableList3 extends ExpandableListActivity {
+    private static final String NAME = "NAME";
+    private static final String IS_EVEN = "IS_EVEN";
+    
+    private ExpandableListAdapter mAdapter;
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
+        List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
+        for (int i = 0; i < 20; i++) {
+            Map<String, String> curGroupMap = new HashMap<String, String>();
+            groupData.add(curGroupMap);
+            curGroupMap.put(NAME, "Group " + i);
+            curGroupMap.put(IS_EVEN, (i % 2 == 0) ? "This group is even" : "This group is odd");
+            
+            List<Map<String, String>> children = new ArrayList<Map<String, String>>();
+            for (int j = 0; j < 15; j++) {
+                Map<String, String> curChildMap = new HashMap<String, String>();
+                children.add(curChildMap);
+                curChildMap.put(NAME, "Child " + j);
+                curChildMap.put(IS_EVEN, (j % 2 == 0) ? "This child is even" : "This child is odd");
+            }
+            childData.add(children);
+        }
+        
+        // Set up our adapter
+        mAdapter = new SimpleExpandableListAdapter(
+                this,
+                groupData,
+                android.R.layout.simple_expandable_list_item_1,
+                new String[] { NAME, IS_EVEN },
+                new int[] { android.R.id.text1, android.R.id.text2 },
+                childData,
+                android.R.layout.simple_expandable_list_item_2,
+                new String[] { NAME, IS_EVEN },
+                new int[] { android.R.id.text1, android.R.id.text2 }
+                );
+        setListAdapter(mAdapter);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
new file mode 100644
index 0000000..86f6ee7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.webkit.WebView;
+import android.widget.ListView;
+import android.widget.ArrayAdapter;
+
+
+/**
+ * Demonstrates the use of non-focusable views.
+ */
+public class Focus1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.focus_1);
+
+        WebView webView = (WebView) findViewById(R.id.rssWebView);
+        webView.loadData(
+                        "<html><body>Can I focus?<br /><a href=\"#\">No I cannot!</a>.</body></html>",
+                        "text/html", "utf-8");
+
+        ListView listView = (ListView) findViewById(R.id.rssListView);
+        listView.setAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, 
+                new String[] {"Ars Technica", "Slashdot", "GameKult"}));
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Focus2.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus2.java
new file mode 100644
index 0000000..77bf8e0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus2.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Focus2 extends Activity {
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.focus_2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Focus3.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus3.java
new file mode 100644
index 0000000..fc3f6df
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus3.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+import com.example.android.apis.R;
+
+public class Focus3 extends Activity {
+    private Button mTopButton;
+    private Button mBottomButton;
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.focus_3);
+
+        mTopButton = (Button) findViewById(R.id.top);
+        mBottomButton = (Button) findViewById(R.id.bottom);
+    }
+
+    public Button getTopButton() {
+        return mTopButton;
+    }
+
+    public Button getBottomButton() {
+        return mBottomButton;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
new file mode 100644
index 0000000..a539a5b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.Gallery;
+import android.widget.ImageView;
+import android.widget.Toast;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class Gallery1 extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.gallery_1);
+
+        // Reference the Gallery view
+        Gallery g = (Gallery) findViewById(R.id.gallery);
+        // Set the adapter to our custom adapter (below)
+        g.setAdapter(new ImageAdapter(this));
+        
+        // Set a item click listener, and just Toast the clicked position
+        g.setOnItemClickListener(new OnItemClickListener() {
+            public void onItemClick(AdapterView parent, View v, int position, long id) {
+                Toast.makeText(Gallery1.this, "" + position, Toast.LENGTH_SHORT).show();
+            }
+        });
+        
+        // We also want to show context menu for longpressed items in the gallery
+        registerForContextMenu(g);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        menu.add(R.string.gallery_2_text);
+    }
+    
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+        Toast.makeText(this, "Longpress: " + info.position, Toast.LENGTH_SHORT).show();
+        return true;
+    }
+
+    public class ImageAdapter extends BaseAdapter {
+        int mGalleryItemBackground;
+        
+        public ImageAdapter(Context c) {
+            mContext = c;
+            // See res/values/attrs.xml for the <declare-styleable> that defines
+            // Gallery1.
+            TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
+            mGalleryItemBackground = a.getResourceId(
+                    R.styleable.Gallery1_android_galleryItemBackground, 0);
+            a.recycle();
+        }
+
+        public int getCount() {
+            return mImageIds.length;
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(mContext);
+
+            i.setImageResource(mImageIds[position]);
+            i.setScaleType(ImageView.ScaleType.FIT_XY);
+            i.setLayoutParams(new Gallery.LayoutParams(136, 88));
+            
+            // The preferred Gallery item background
+            i.setBackgroundResource(mGalleryItemBackground);
+            
+            return i;
+        }
+
+        private Context mContext;
+
+        private Integer[] mImageIds = {
+                R.drawable.gallery_photo_1,
+                R.drawable.gallery_photo_2,
+                R.drawable.gallery_photo_3,
+                R.drawable.gallery_photo_4,
+                R.drawable.gallery_photo_5,
+                R.drawable.gallery_photo_6,
+                R.drawable.gallery_photo_7,
+                R.drawable.gallery_photo_8
+        };
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
new file mode 100644
index 0000000..2eea1ff
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.Contacts.People;
+import android.os.Bundle;
+import android.widget.Gallery;
+import android.widget.SimpleCursorAdapter;
+import android.widget.SpinnerAdapter;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+public class Gallery2 extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.gallery_2);
+
+        // Get a cursor with all people
+        Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+        startManagingCursor(c);
+        
+        SpinnerAdapter adapter = new SimpleCursorAdapter(this,
+        // Use a template that displays a text view
+                android.R.layout.simple_gallery_item,
+                // Give the cursor to the list adatper
+                c,
+                // Map the NAME column in the people database to...
+                new String[] {People.NAME},
+                // The "text1" view defined in the XML template
+                new int[] { android.R.id.text1 });
+
+        Gallery g = (Gallery) findViewById(R.id.gallery);
+        g.setAdapter(adapter);
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Grid1.java b/samples/ApiDemos/src/com/example/android/apis/view/Grid1.java
new file mode 100644
index 0000000..d52d4f5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Grid1.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+import com.example.android.apis.R;
+
+
+public class Grid1 extends Activity {
+
+    GridView mGrid;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        loadApps(); // do this in onresume?
+
+        setContentView(R.layout.grid_1);
+        mGrid = (GridView) findViewById(R.id.myGrid);
+        mGrid.setAdapter(new AppsAdapter());
+    }
+
+    private List<ResolveInfo> mApps;
+
+    private void loadApps() {
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        mApps = getPackageManager().queryIntentActivities(mainIntent, 0);
+    }
+
+    public class AppsAdapter extends BaseAdapter {
+        public AppsAdapter() {
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i;
+
+            if (convertView == null) {
+                i = new ImageView(Grid1.this);
+                i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+                i.setLayoutParams(new GridView.LayoutParams(50, 50));
+            } else {
+                i = (ImageView) convertView;
+            }
+
+            ResolveInfo info = mApps.get(position);
+            i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
+
+            return i;
+        }
+
+
+        public final int getCount() {
+            return mApps.size();
+        }
+
+        public final Object getItem(int position) {
+            return mApps.get(position);
+        }
+
+        public final long getItemId(int position) {
+            return position;
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Grid2.java b/samples/ApiDemos/src/com/example/android/apis/view/Grid2.java
new file mode 100644
index 0000000..916eccb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Grid2.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+/**
+ * A grid that displays a set of framed photos.
+ *
+ */
+public class Grid2 extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.grid_2);
+
+        GridView g = (GridView) findViewById(R.id.myGrid);
+        g.setAdapter(new ImageAdapter(this));
+    }
+
+    public class ImageAdapter extends BaseAdapter {
+        public ImageAdapter(Context c) {
+            mContext = c;
+        }
+
+        public int getCount() {
+            return mThumbIds.length;
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView imageView;
+            if (convertView == null) {
+                imageView = new ImageView(mContext);
+                imageView.setLayoutParams(new GridView.LayoutParams(45, 45));
+                imageView.setAdjustViewBounds(false);
+                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+                imageView.setPadding(8, 8, 8, 8);
+            } else {
+                imageView = (ImageView) convertView;
+            }
+
+            imageView.setImageResource(mThumbIds[position]);
+
+            return imageView;
+        }
+
+        private Context mContext;
+
+        private Integer[] mThumbIds = {
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+                R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+                R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7,
+        };
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ImageButton1.java b/samples/ApiDemos/src/com/example/android/apis/view/ImageButton1.java
new file mode 100644
index 0000000..5d1fb19
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ImageButton1.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+import com.example.android.apis.R;
+
+
+public class ImageButton1 extends Activity {
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.image_button_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java b/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
new file mode 100644
index 0000000..f72b623
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.animation.AnimationUtils;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.Gallery;
+import android.widget.Gallery.LayoutParams;
+import android.widget.ImageSwitcher;
+import android.widget.ImageView;
+import android.widget.ViewSwitcher;
+
+
+public class ImageSwitcher1 extends Activity implements
+        AdapterView.OnItemSelectedListener, ViewSwitcher.ViewFactory {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        setContentView(R.layout.image_switcher_1);
+
+        mSwitcher = (ImageSwitcher) findViewById(R.id.switcher);
+        mSwitcher.setFactory(this);
+        mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
+                android.R.anim.fade_in));
+        mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
+                android.R.anim.fade_out));
+
+        Gallery g = (Gallery) findViewById(R.id.gallery);
+        g.setAdapter(new ImageAdapter(this));
+        g.setOnItemSelectedListener(this);
+    }
+
+    public void onItemSelected(AdapterView parent, View v, int position, long id) {
+        mSwitcher.setImageResource(mImageIds[position]);
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+    }
+
+    public View makeView() {
+        ImageView i = new ImageView(this);
+        i.setBackgroundColor(0xFF000000);
+        i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+        i.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT,
+                LayoutParams.FILL_PARENT));
+        return i;
+    }
+
+    private ImageSwitcher mSwitcher;
+
+    public class ImageAdapter extends BaseAdapter {
+        public ImageAdapter(Context c) {
+            mContext = c;
+        }
+
+        public int getCount() {
+            return mThumbIds.length;
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(mContext);
+
+            i.setImageResource(mThumbIds[position]);
+            i.setAdjustViewBounds(true);
+            i.setLayoutParams(new Gallery.LayoutParams(
+                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+            i.setBackgroundResource(R.drawable.picture_frame);
+            return i;
+        }
+
+        private Context mContext;
+
+    }
+
+    private Integer[] mThumbIds = {
+            R.drawable.sample_thumb_0, R.drawable.sample_thumb_1,
+            R.drawable.sample_thumb_2, R.drawable.sample_thumb_3,
+            R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+            R.drawable.sample_thumb_6, R.drawable.sample_thumb_7};
+
+    private Integer[] mImageIds = {
+            R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2,
+            R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5,
+            R.drawable.sample_6, R.drawable.sample_7};
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ImageView1.java b/samples/ApiDemos/src/com/example/android/apis/view/ImageView1.java
new file mode 100644
index 0000000..f63b01a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ImageView1.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.os.Bundle;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Demonstrates setting size constraints on {@link android.widget.ImageView}
+ *
+ */
+public class ImageView1 extends Activity {
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.image_view_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionFocus.java b/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionFocus.java
new file mode 100644
index 0000000..a664ab9
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionFocus.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * {@link android.view.View#requestFocus(int, android.graphics.Rect)}
+ * and
+ * {@link android.view.View#onFocusChanged(boolean, int, android.graphics.Rect)}
+ * work together to give a newly focused item a hint about the most interesting
+ * rectangle of the previously focused view.  The view taking focus can use this
+ * to set an internal selection more appropriate using this rect.
+ *
+ * This Activity excercises that behavior using three adjacent {@link InternalSelectionView}
+ * that report interesting rects when giving up focus, and use interesting rects
+ * when taking focus to best select the internal row to show as selected.
+ *
+ * Were {@link InternalSelectionView} not to override {@link android.view.View#getFocusedRect}, or
+ * {@link android.view.View#onFocusChanged(boolean, int, android.graphics.Rect)}, the focus would
+ * jump to some default internal selection (the top) and not allow for the smooth handoff.
+ */
+public class InternalSelectionFocus extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.HORIZONTAL);
+        layout.setLayoutParams(new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.FILL_PARENT,
+                ViewGroup.LayoutParams.FILL_PARENT));
+
+        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
+                ViewGroup.LayoutParams.FILL_PARENT, 1);
+
+        final InternalSelectionView leftColumn = new InternalSelectionView(this, 5, "left column");
+        leftColumn.setLayoutParams(params);
+        leftColumn.setPadding(10, 10, 10, 10);
+        layout.addView(leftColumn);
+
+        final InternalSelectionView middleColumn = new InternalSelectionView(this, 5, "middle column");
+        middleColumn.setLayoutParams(params);
+        middleColumn.setPadding(10, 10, 10, 10);
+        layout.addView(middleColumn);
+
+        final InternalSelectionView rightColumn = new InternalSelectionView(this, 5, "right column");
+        rightColumn.setLayoutParams(params);
+        rightColumn.setPadding(10, 10, 10, 10);
+        layout.addView(rightColumn);
+
+        setContentView(layout);
+    }
+
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionScroll.java b/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionScroll.java
new file mode 100644
index 0000000..fe607e2
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionScroll.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+
+/**
+ * Demonstrates how a well behaved view with internal selection
+ * ({@link InternalSelectionView}) can cause its parent {@link android.widget.ScrollView}
+ * to scroll to keep the internally interesting rectangle on the screen.
+ *
+ * {@link InternalSelectionView} achieves this by calling {@link android.view.View#requestRectangleOnScreen}
+ * each time its internal selection changes.
+ *
+ * {@link android.widget.ScrollView}, in turn, implements {@link android.view.View#requestRectangleOnScreen}
+ * thereby acheiving the result.  Note that {@link android.widget.ListView} also implements the
+ * method, so views that call {@link android.view.View#requestRectangleOnScreen} that are embedded
+ * within either {@link android.widget.ScrollView}s or {@link android.widget.ListView}s can
+ * expect to keep their internal interesting rectangle visible.
+ */
+public class InternalSelectionScroll extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        ScrollView sv = new ScrollView(this);
+        ViewGroup.LayoutParams svLp = new ScrollView.LayoutParams(
+                ViewGroup.LayoutParams.FILL_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        LinearLayout ll = new LinearLayout(this);
+        ll.setLayoutParams(svLp);
+        sv.addView(ll);
+
+        InternalSelectionView isv = new InternalSelectionView(this, 10);
+        int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
+        LinearLayout.LayoutParams llLp = new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.FILL_PARENT,
+                2 * screenHeight);  // 2x screen height to ensure scrolling
+        isv.setLayoutParams(llLp);
+        ll.addView(isv);
+        
+        setContentView(sv);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionView.java b/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionView.java
new file mode 100644
index 0000000..3ef8403
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionView.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+
+
+
+/**
+ * A view that has a known number of selectable rows, and maintains a notion of which
+ * row is selected. The rows take up the
+ * entire width of the view.  The height of the view is divided evenly among
+ * the rows.
+ *
+ * Notice what this view does to be a good citizen w.r.t its internal selection:
+ * 1) calls {@link View#requestRectangleOnScreen} each time the selection changes due to
+ *    internal navigation.
+ * 2) overrides {@link View#getFocusedRect} by filling in the rectangle of the currently
+ *    selected row
+ * 3) overrides {@link View#onFocusChanged} and sets selection appropriately according to
+ *    the previously focused rectangle.
+ */
+public class InternalSelectionView extends View {
+
+    private Paint mPainter = new Paint();
+    private Paint mTextPaint = new Paint();
+    private Rect mTempRect = new Rect();
+
+    private int mNumRows = 5;
+    private int mSelectedRow = 0;
+    private final int mEstimatedPixelHeight = 10;
+
+    private Integer mDesiredHeight = null;
+    private String mLabel = null;
+
+
+    public InternalSelectionView(Context context, int numRows) {
+        this(context, numRows, "");
+    }
+    
+    public InternalSelectionView(Context context, int numRows, String label) {
+        super(context);
+        mNumRows = numRows;
+        mLabel = label;
+        init();
+    }
+
+    public InternalSelectionView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        setFocusable(true);
+        mTextPaint.setAntiAlias(true);
+        mTextPaint.setTextSize(10);
+        mTextPaint.setColor(Color.WHITE);
+    }
+
+    public int getNumRows() {
+        return mNumRows;
+    }
+
+    public int getSelectedRow() {
+        return mSelectedRow;
+    }
+
+    public void setDesiredHeight(int desiredHeight) {
+        mDesiredHeight = desiredHeight;
+    }
+
+    public String getLabel() {
+        return mLabel;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        setMeasuredDimension(
+            measureWidth(widthMeasureSpec),
+            measureHeight(heightMeasureSpec));
+    }
+
+    private int measureWidth(int measureSpec) {
+        int specMode = MeasureSpec.getMode(measureSpec);
+        int specSize = MeasureSpec.getSize(measureSpec);
+
+        int desiredWidth = 300 + getPaddingLeft() + getPaddingRight();
+        if (specMode == MeasureSpec.EXACTLY) {
+            // We were told how big to be
+            return specSize;
+        } else if (specMode == MeasureSpec.AT_MOST) {
+            return desiredWidth < specSize ? desiredWidth : specSize;
+        } else {
+            return desiredWidth;
+        }
+    }
+
+    private int measureHeight(int measureSpec) {
+        int specMode = MeasureSpec.getMode(measureSpec);
+        int specSize = MeasureSpec.getSize(measureSpec);
+
+        int desiredHeight = mDesiredHeight != null ?
+                mDesiredHeight :
+                mNumRows * mEstimatedPixelHeight + getPaddingTop() + getPaddingBottom();
+        if (specMode == MeasureSpec.EXACTLY) {
+            // We were told how big to be
+            return specSize;
+        } else if (specMode == MeasureSpec.AT_MOST) {
+            return desiredHeight < specSize ? desiredHeight : specSize;
+        } else {
+            return desiredHeight;
+        }
+    }
+
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+
+        int rowHeight = getRowHeight();
+
+        int rectTop = getPaddingTop();
+        int rectLeft = getPaddingLeft();
+        int rectRight = getWidth() - getPaddingRight();
+        for (int i = 0; i < mNumRows; i++) {
+
+            mPainter.setColor(Color.BLACK);
+            mPainter.setAlpha(0x20);
+
+            // draw background rect
+            mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight);
+            canvas.drawRect(mTempRect, mPainter);
+
+            // draw forground rect
+            if (i == mSelectedRow && hasFocus()) {
+                mPainter.setColor(Color.RED);
+                mPainter.setAlpha(0xF0);
+                mTextPaint.setAlpha(0xFF);
+            } else {
+                mPainter.setColor(Color.BLACK);
+                mPainter.setAlpha(0x40);
+                mTextPaint.setAlpha(0xF0);
+            }
+            mTempRect.set(rectLeft + 2, rectTop + 2,
+                    rectRight - 2, rectTop + rowHeight - 2);
+            canvas.drawRect(mTempRect, mPainter);
+
+            // draw text to help when visually inspecting
+            canvas.drawText(
+                    Integer.toString(i),
+                    rectLeft + 2,
+                    rectTop + 2 - (int) mTextPaint.ascent(),
+                    mTextPaint);
+
+            rectTop += rowHeight;
+        }
+    }
+
+    private int getRowHeight() {
+        return (getHeight() - getPaddingTop() - getPaddingBottom()) / mNumRows;
+    }
+
+    public void getRectForRow(Rect rect, int row) {
+        final int rowHeight = getRowHeight();
+        final int top = getPaddingTop() + row * rowHeight;
+        rect.set(getPaddingLeft(),
+                top,
+                getWidth() - getPaddingRight(),
+                top + rowHeight);
+    }
+
+
+    void ensureRectVisible() {
+        getRectForRow(mTempRect, mSelectedRow);
+        requestRectangleOnScreen(mTempRect);
+    }
+
+
+    /* (non-Javadoc)
+    * @see android.view.KeyEvent.Callback#onKeyDown(int, android.view.KeyEvent)
+    */
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch(event.getKeyCode()) {
+            case KeyEvent.KEYCODE_DPAD_UP:
+                if (mSelectedRow > 0) {
+                    mSelectedRow--;
+                    invalidate();
+                    ensureRectVisible();
+                    return true;
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                if (mSelectedRow < (mNumRows - 1)) {
+                    mSelectedRow++;
+                    invalidate();
+                    ensureRectVisible();
+                    return true;
+                }
+                break;
+        }
+        return false;
+    }
+
+
+    @Override
+    public void getFocusedRect(Rect r) {
+        getRectForRow(r, mSelectedRow);
+    }
+
+    @Override
+    protected void onFocusChanged(boolean focused, int direction,
+            Rect previouslyFocusedRect) {
+        super.onFocusChanged(focused, direction, previouslyFocusedRect);
+
+        if (focused) {
+            switch (direction) {
+                case View.FOCUS_DOWN:
+                    mSelectedRow = 0;
+                    break;
+                case View.FOCUS_UP:
+                    mSelectedRow = mNumRows - 1;
+                    break;
+                case View.FOCUS_LEFT:  // fall through
+                case View.FOCUS_RIGHT:
+                    // set the row that is closest to the rect
+                    if (previouslyFocusedRect != null) {
+                        int y = previouslyFocusedRect.top
+                                + (previouslyFocusedRect.height() / 2);
+                        int yPerRow = getHeight() / mNumRows;
+                        mSelectedRow = y / yPerRow;
+                    } else {
+                        mSelectedRow = 0;
+                    }
+                    break;
+                default:
+                    // can't gleam any useful information about what internal
+                    // selection should be...
+                    return;
+            }
+            invalidate();
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (mLabel != null) {
+            return mLabel;
+        }
+        return super.toString();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LabelView.java b/samples/ApiDemos/src/com/example/android/apis/view/LabelView.java
new file mode 100644
index 0000000..b98a5b5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LabelView.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Example of how to write a custom subclass of View. LabelView
+ * is used to draw simple text views. Note that it does not handle
+ * styled text or right-to-left writing systems.
+ *
+ */
+public class LabelView extends View {
+    private Paint mTextPaint;
+    private String mText;
+    private int mAscent;
+    
+    /**
+     * Constructor.  This version is only needed if you will be instantiating
+     * the object manually (not from a layout XML file).
+     * @param context
+     */
+    public LabelView(Context context) {
+        super(context);
+        initLabelView();
+    }
+
+    /**
+     * Construct object, initializing with any attributes we understand from a
+     * layout file. These attributes are defined in
+     * SDK/assets/res/any/classes.xml.
+     * 
+     * @see android.view.View#View(android.content.Context, android.util.AttributeSet)
+     */
+    public LabelView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initLabelView();
+
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.LabelView);
+
+        CharSequence s = a.getString(R.styleable.LabelView_text);
+        if (s != null) {
+            setText(s.toString());
+        }
+
+        // Retrieve the color(s) to be used for this view and apply them.
+        // Note, if you only care about supporting a single color, that you
+        // can instead call a.getColor() and pass that to setTextColor().
+        setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF000000));
+
+        int textSize = a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);
+        if (textSize > 0) {
+            setTextSize(textSize);
+        }
+
+        a.recycle();
+    }
+
+    private final void initLabelView() {
+        mTextPaint = new Paint();
+        mTextPaint.setAntiAlias(true);
+        mTextPaint.setTextSize(16);
+        mTextPaint.setColor(0xFF000000);
+        setPadding(3, 3, 3, 3);
+    }
+
+    /**
+     * Sets the text to display in this label
+     * @param text The text to display. This will be drawn as one line.
+     */
+    public void setText(String text) {
+        mText = text;
+        requestLayout();
+        invalidate();
+    }
+
+    /**
+     * Sets the text size for this label
+     * @param size Font size
+     */
+    public void setTextSize(int size) {
+        mTextPaint.setTextSize(size);
+        requestLayout();
+        invalidate();
+    }
+
+    /**
+     * Sets the text color for this label.
+     * @param color ARGB value for the text
+     */
+    public void setTextColor(int color) {
+        mTextPaint.setColor(color);
+        invalidate();
+    }
+
+    /**
+     * @see android.view.View#measure(int, int)
+     */
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        setMeasuredDimension(measureWidth(widthMeasureSpec),
+                measureHeight(heightMeasureSpec));
+    }
+
+    /**
+     * Determines the width of this view
+     * @param measureSpec A measureSpec packed into an int
+     * @return The width of the view, honoring constraints from measureSpec
+     */
+    private int measureWidth(int measureSpec) {
+        int result = 0;
+        int specMode = MeasureSpec.getMode(measureSpec);
+        int specSize = MeasureSpec.getSize(measureSpec);
+
+        if (specMode == MeasureSpec.EXACTLY) {
+            // We were told how big to be
+            result = specSize;
+        } else {
+            // Measure the text
+            result = (int) mTextPaint.measureText(mText) + getPaddingLeft()
+                    + getPaddingRight();
+            if (specMode == MeasureSpec.AT_MOST) {
+                // Respect AT_MOST value if that was what is called for by measureSpec
+                result = Math.min(result, specSize);
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Determines the height of this view
+     * @param measureSpec A measureSpec packed into an int
+     * @return The height of the view, honoring constraints from measureSpec
+     */
+    private int measureHeight(int measureSpec) {
+        int result = 0;
+        int specMode = MeasureSpec.getMode(measureSpec);
+        int specSize = MeasureSpec.getSize(measureSpec);
+
+        mAscent = (int) mTextPaint.ascent();
+        if (specMode == MeasureSpec.EXACTLY) {
+            // We were told how big to be
+            result = specSize;
+        } else {
+            // Measure the text (beware: ascent is a negative number)
+            result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop()
+                    + getPaddingBottom();
+            if (specMode == MeasureSpec.AT_MOST) {
+                // Respect AT_MOST value if that was what is called for by measureSpec
+                result = Math.min(result, specSize);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Render the text
+     * 
+     * @see android.view.View#onDraw(android.graphics.Canvas)
+     */
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation1.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation1.java
new file mode 100644
index 0000000..19e1834
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation1.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class LayoutAnimation1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        loadApps();
+
+        setContentView(R.layout.layout_animation_1);
+        GridView grid = (GridView) findViewById(R.id.grid);
+        grid.setAdapter(new LayoutAnimation1.AppsAdapter());
+    }
+
+    private List<ResolveInfo> mApps;
+
+    private void loadApps() {
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        mApps = getPackageManager().queryIntentActivities(mainIntent, 0);
+    }
+
+    public class AppsAdapter extends BaseAdapter {
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(LayoutAnimation1.this);
+
+            ResolveInfo info = mApps.get(position % mApps.size());
+
+            i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
+            i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+            i.setLayoutParams(new GridView.LayoutParams(36, 36));
+            return i;
+        }
+
+
+        public final int getCount() {
+            return Math.min(32, mApps.size());
+        }
+
+        public final Object getItem(int position) {
+            return mApps.get(position % mApps.size());
+        }
+
+        public final long getItemId(int position) {
+            return position;
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation2.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation2.java
new file mode 100644
index 0000000..1c00145
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation2.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.LayoutAnimationController;
+import android.view.animation.TranslateAnimation;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+public class LayoutAnimation2 extends ListActivity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mStrings));
+
+        AnimationSet set = new AnimationSet(true);
+
+        Animation animation = new AlphaAnimation(0.0f, 1.0f);
+        animation.setDuration(50);
+        set.addAnimation(animation);
+
+        animation = new TranslateAnimation(
+            Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
+            Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f
+        );
+        animation.setDuration(100);
+        set.addAnimation(animation);
+
+        LayoutAnimationController controller =
+                new LayoutAnimationController(set, 0.5f);
+        ListView listView = getListView();        
+        listView.setLayoutAnimation(controller);
+    }
+
+    private String[] mStrings = {
+        "Bordeaux",
+        "Lyon",
+        "Marseille",
+        "Nancy",
+        "Paris",
+        "Toulouse",
+        "Strasbourg"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation3.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation3.java
new file mode 100644
index 0000000..edc2926
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation3.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.view.View;
+
+public class LayoutAnimation3 extends ListActivity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.layout_animation_3);
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mStrings));
+    }
+
+    private String[] mStrings = {
+        "Bordeaux",
+        "Lyon",
+        "Marseille",
+        "Nancy",
+        "Paris",
+        "Toulouse",
+        "Strasbourg"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation4.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation4.java
new file mode 100644
index 0000000..73b338b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation4.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class LayoutAnimation4 extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        loadApps();
+
+        setContentView(R.layout.layout_animation_4);
+        GridView grid = (GridView) findViewById(R.id.grid);
+        grid.setAdapter(new AppsAdapter());
+
+    }
+
+    private List<ResolveInfo> mApps;
+
+    private void loadApps() {
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        mApps = getPackageManager().queryIntentActivities(mainIntent, 0);
+    }
+
+    public class AppsAdapter extends BaseAdapter {
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(LayoutAnimation4.this);
+
+            ResolveInfo info = mApps.get(position % mApps.size());
+
+            i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
+            i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+            i.setLayoutParams(new GridView.LayoutParams(36, 36));
+            return i;
+        }
+
+
+        public final int getCount() {
+            return Math.min(32, mApps.size());
+        }
+
+        public final Object getItem(int position) {
+            return mApps.get(position % mApps.size());
+        }
+
+        public final long getItemId(int position) {
+            return position;
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation5.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation5.java
new file mode 100644
index 0000000..8ed8a36
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation5.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Gallery;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class LayoutAnimation5 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        loadApps();
+
+        setContentView(R.layout.layout_animation_5);
+        GridView grid = (GridView) findViewById(R.id.grid);
+        grid.setAdapter(new AppsAdapter());
+    }
+
+    private List<ResolveInfo> mApps;
+
+    private void loadApps() {
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        mApps = getPackageManager().queryIntentActivities(mainIntent, 0);
+    }
+
+    public class AppsAdapter extends BaseAdapter {
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(LayoutAnimation5.this);
+
+            ResolveInfo info = mApps.get(position % mApps.size());
+
+            i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
+            i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+            i.setLayoutParams(new GridView.LayoutParams(36, 36));
+            return i;
+        }
+
+
+        public final int getCount() {
+            return Math.min(32, mApps.size());
+        }
+
+        public final Object getItem(int position) {
+            return mApps.get(position % mApps.size());
+        }
+
+        public final long getItemId(int position) {
+            return position;
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation6.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation6.java
new file mode 100644
index 0000000..ef7917e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation6.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class LayoutAnimation6 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        loadApps();
+
+        setContentView(R.layout.layout_animation_6);
+        GridView grid = (GridView) findViewById(R.id.grid);
+        grid.setAdapter(new AppsAdapter());
+    }
+
+    private List<ResolveInfo> mApps;
+
+    private void loadApps() {
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        mApps = getPackageManager().queryIntentActivities(mainIntent, 0);
+    }
+
+    public class AppsAdapter extends BaseAdapter {
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(LayoutAnimation6.this);
+
+            ResolveInfo info = mApps.get(position % mApps.size());
+
+            i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
+            i.setScaleType(ImageView.ScaleType.FIT_CENTER);
+            i.setLayoutParams(new GridView.LayoutParams(36, 36));
+            return i;
+        }
+
+
+        public final int getCount() {
+            return Math.min(32, mApps.size());
+        }
+
+        public final Object getItem(int position) {
+            return mApps.get(position % mApps.size());
+        }
+
+        public final long getItemId(int position) {
+            return position;
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation7.java b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation7.java
new file mode 100644
index 0000000..6eeb429
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation7.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.GridLayoutAnimationController;
+import android.widget.BaseAdapter;
+import android.widget.Gallery;
+import android.widget.GridView;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class LayoutAnimation7 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.layout_animation_7);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout1.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout1.java
new file mode 100644
index 0000000..fcf4924
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout1.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * A simple linear layout where the height of the layout is the sum of its children.
+ */
+public class LinearLayout1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout10.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout10.java
new file mode 100644
index 0000000..eb22d9a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout10.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 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;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates the use of LinearLayout backgrounds to group labels,
+ * EditTexts, and buttons,
+ */
+public class LinearLayout10 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_10);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout2.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout2.java
new file mode 100644
index 0000000..044f2b6
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout2.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * A simple linear layout that fills the screen vertically, but the children are not padded.
+ */
+public class LinearLayout2 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout3.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout3.java
new file mode 100644
index 0000000..2468dcd
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout3.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * A simple linear layout that fills the screen vertically, and the middle child is padded with extra space.
+ */
+public class LinearLayout3 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_3);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout4.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout4.java
new file mode 100644
index 0000000..f3d1d1b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout4.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates a horizontal linear layout with equally sized columns.
+ *
+ */
+public class LinearLayout4 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_4);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout5.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout5.java
new file mode 100644
index 0000000..d3b2a25
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout5.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates building a simple form with nested LinearLayouts.
+ *
+ */
+public class LinearLayout5 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_5);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout6.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout6.java
new file mode 100644
index 0000000..88745fb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout6.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates using the uniformSize attribute
+ *
+ */
+public class LinearLayout6 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_6);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout7.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout7.java
new file mode 100644
index 0000000..32c787f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout7.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates using fill_parent within a linear layout whose size is not fixed.
+ *
+ */
+public class LinearLayout7 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_7);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout8.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout8.java
new file mode 100644
index 0000000..5896782
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout8.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.Gravity;
+import android.view.MenuItem;
+import android.widget.LinearLayout;
+
+
+/**
+ * Demonstrates horizontal and vertical gravity
+ */
+public class LinearLayout8 extends Activity {
+
+    private LinearLayout mLinearLayout;
+
+    // Menu item Ids
+    public static final int VERTICAL_ID = Menu.FIRST;
+    public static final int HORIZONTAL_ID = Menu.FIRST + 1;
+
+    public static final int TOP_ID = Menu.FIRST + 2;
+    public static final int MIDDLE_ID = Menu.FIRST + 3;
+    public static final int BOTTOM_ID = Menu.FIRST + 4;
+
+    public static final int LEFT_ID = Menu.FIRST + 5;
+    public static final int CENTER_ID = Menu.FIRST + 6;
+    public static final int RIGHT_ID = Menu.FIRST + 7;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_8);
+        mLinearLayout = (LinearLayout)findViewById(R.id.layout);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, VERTICAL_ID, 0, R.string.linear_layout_8_vertical);
+        menu.add(0, HORIZONTAL_ID, 0, R.string.linear_layout_8_horizontal);
+        menu.add(0, TOP_ID, 0, R.string.linear_layout_8_top);
+        menu.add(0, MIDDLE_ID, 0, R.string.linear_layout_8_middle);
+        menu.add(0, BOTTOM_ID, 0, R.string.linear_layout_8_bottom);
+        menu.add(0, LEFT_ID, 0, R.string.linear_layout_8_left);
+        menu.add(0, CENTER_ID, 0, R.string.linear_layout_8_center);
+        menu.add(0, RIGHT_ID, 0, R.string.linear_layout_8_right);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+
+        case VERTICAL_ID:
+            mLinearLayout.setOrientation(LinearLayout.VERTICAL);
+            return true;
+        case HORIZONTAL_ID:
+            mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
+            return true;
+
+        case TOP_ID:
+            mLinearLayout.setVerticalGravity(Gravity.TOP);
+            return true;
+        case MIDDLE_ID:
+            mLinearLayout.setVerticalGravity(Gravity.CENTER_VERTICAL);
+            return true;
+        case BOTTOM_ID:
+            mLinearLayout.setVerticalGravity(Gravity.BOTTOM);
+            return true;
+
+        case LEFT_ID:
+            mLinearLayout.setHorizontalGravity(Gravity.LEFT);
+            return true;
+        case CENTER_ID:
+            mLinearLayout.setHorizontalGravity(Gravity.CENTER_HORIZONTAL);
+            return true;
+        case RIGHT_ID:
+            mLinearLayout.setHorizontalGravity(Gravity.RIGHT);
+            return true;
+
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout9.java b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout9.java
new file mode 100644
index 0000000..d120b1e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout9.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ListView;
+import android.widget.ArrayAdapter;
+
+/**
+ * Demonstrates how the layout_weight attribute can shrink an element too big
+ * to fit on screen.
+ */
+public class LinearLayout9 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.linear_layout_9);
+        ListView list = (ListView) findViewById(R.id.list);
+        list.setAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, AutoComplete1.COUNTRIES));
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List1.java b/samples/ApiDemos/src/com/example/android/apis/view/List1.java
new file mode 100644
index 0000000..5861923
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List1.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+
+
+/**
+ * A list view example where the 
+ * data for the list comes from an array of strings.
+ */
+public class List1 extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Use an existing ListAdapter that will map an array
+        // of strings to TextViews
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mStrings));
+        getListView().setTextFilterEnabled(true);
+    }
+
+    private String[] mStrings = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List10.java b/samples/ApiDemos/src/com/example/android/apis/view/List10.java
new file mode 100644
index 0000000..57e0bb1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List10.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.ListActivity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * This example shows how to use choice mode on a list. This list is 
+ * in CHOICE_MODE_SINGLE mode, which means the items behave like
+ * checkboxes.
+ */
+public class List10 extends ListActivity {
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_single_choice, GENRES));
+        
+        final ListView listView = getListView();
+
+        listView.setItemsCanFocus(false);
+        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+    }
+
+
+    private static final String[] GENRES = new String[] {
+        "Action", "Adventure", "Animation", "Children", "Comedy", "Documentary", "Drama",
+        "Foreign", "History", "Independent", "Romance", "Sci-Fi", "Television", "Thriller"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List11.java b/samples/ApiDemos/src/com/example/android/apis/view/List11.java
new file mode 100644
index 0000000..71d77e5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List11.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.ListActivity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * This example shows how to use choice mode on a list. This list is 
+ * in CHOICE_MODE_MULTIPLE mode, which means the items behave like
+ * checkboxes.
+ */
+public class List11 extends ListActivity {
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_multiple_choice, GENRES));
+        
+        final ListView listView = getListView();
+
+        listView.setItemsCanFocus(false);
+        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+    }
+
+
+    private static final String[] GENRES = new String[] {
+        "Action", "Adventure", "Animation", "Children", "Comedy", "Documentary", "Drama",
+        "Foreign", "History", "Independent", "Romance", "Sci-Fi", "Television", "Thriller"
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List12.java b/samples/ApiDemos/src/com/example/android/apis/view/List12.java
new file mode 100644
index 0000000..0867fc5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List12.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnKeyListener;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+
+import com.example.android.apis.R;
+
+import java.util.ArrayList;
+
+/**
+ * Demonstrates the using a list view in transcript mode
+ *
+ */
+public class List12 extends ListActivity implements OnClickListener, OnKeyListener {
+
+    private EditText mUserText;
+    
+    private ArrayAdapter<String> mAdapter;
+    
+    private ArrayList<String> mStrings = new ArrayList<String>();
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.list_12);
+        
+        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings);
+        
+        setListAdapter(mAdapter);
+        
+        mUserText = (EditText) findViewById(R.id.userText);
+
+        mUserText.setOnClickListener(this);
+        mUserText.setOnKeyListener(this);
+    }
+
+    public void onClick(View v) {
+        sendText();
+    }
+
+    private void sendText() {
+        String text = mUserText.getText().toString();
+        mAdapter.add(text);
+        mUserText.setText(null);
+    }
+
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_DPAD_CENTER:
+                case KeyEvent.KEYCODE_ENTER:
+                    sendText();
+                    return true;
+            }
+        }
+        return false;
+    }
+    
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List13.java b/samples/ApiDemos/src/com/example/android/apis/view/List13.java
new file mode 100644
index 0000000..b3087be
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List13.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2008 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.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.AbsListView.OnScrollListener;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Demonstrates how a list can avoid expensive operations during scrolls or flings. In this
+ * case, we pretend that binding a view to its data is slow (even though it really isn't). When
+ * a scroll/fling is happening, the adapter binds the view to temporary data. After the scroll/fling
+ * has finished, the temporary data is replace with the actual data.
+ *
+ */
+public class List13 extends ListActivity implements ListView.OnScrollListener {
+
+    private TextView mStatus;
+    
+    private boolean mBusy = false;
+    
+    /**
+     * Will not bind views while the list is scrolling
+     * 
+     */
+    private class SlowAdapter extends BaseAdapter {
+        private LayoutInflater mInflater;
+        
+        public SlowAdapter(Context context) {
+            mContext = context;
+            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        /**
+         * The number of items in the list is determined by the number of speeches
+         * in our array.
+         * 
+         * @see android.widget.ListAdapter#getCount()
+         */
+        public int getCount() {
+            return mStrings.length;
+        }
+
+        /**
+         * Since the data comes from an array, just returning the index is
+         * sufficent to get at the data. If we were using a more complex data
+         * structure, we would return whatever object represents one row in the
+         * list.
+         * 
+         * @see android.widget.ListAdapter#getItem(int)
+         */
+        public Object getItem(int position) {
+            return position;
+        }
+
+        /**
+         * Use the array index as a unique id.
+         * 
+         * @see android.widget.ListAdapter#getItemId(int)
+         */
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Make a view to hold each row.
+         * 
+         * @see android.widget.ListAdapter#getView(int, android.view.View,
+         *      android.view.ViewGroup)
+         */
+        public View getView(int position, View convertView, ViewGroup parent) {
+            TextView text;
+            
+            if (convertView == null) {
+                text = (TextView)mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
+            } else {
+                text = (TextView)convertView;
+            }
+
+            if (!mBusy) {
+                text.setText(mStrings[position]);
+                // Null tag means the view has the correct data
+                text.setTag(null);
+            } else {
+                text.setText("Loading...");
+                // Non-null tag means the view still needs to load it's data
+                text.setTag(this);
+            }
+
+            return text;
+        }
+
+        /**
+         * Remember our context so we can use it when constructing views.
+         */
+        private Context mContext;
+    }
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.list_13);
+        mStatus = (TextView) findViewById(R.id.status);
+        mStatus.setText("Idle");
+        
+        // Use an existing ListAdapter that will map an array
+        // of strings to TextViews
+        setListAdapter(new SlowAdapter(this));
+        
+        getListView().setOnScrollListener(this);
+    }
+    
+    
+    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+            int totalItemCount) {
+    }
+    
+
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+        switch (scrollState) {
+        case OnScrollListener.SCROLL_STATE_IDLE:
+            mBusy = false;
+            
+            int first = view.getFirstVisiblePosition();
+            int count = view.getChildCount();
+            for (int i=0; i<count; i++) {
+                TextView t = (TextView)view.getChildAt(i);
+                if (t.getTag() != null) {
+                    t.setText(mStrings[first + i]);
+                    t.setTag(null);
+                }
+            }
+            
+            mStatus.setText("Idle");
+            break;
+        case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
+            mBusy = true;
+            mStatus.setText("Touch scroll");
+            break;
+        case OnScrollListener.SCROLL_STATE_FLING:
+            mBusy = true;
+            mStatus.setText("Fling");
+            break;
+        }
+    }
+
+    private String[] mStrings = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
+            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
+            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
+            "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh",
+            "Anthoriro", "Appenzell", "Aragon", "Ardi Gasna", "Ardrahan",
+            "Armenian String", "Aromes au Gene de Marc", "Asadero", "Asiago",
+            "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", "Babybel",
+            "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal",
+            "Banon", "Barry's Bay Cheddar", "Basing", "Basket Cheese",
+            "Bath Cheese", "Bavarian Bergkase", "Baylough", "Beaufort",
+            "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir",
+            "Bierkase", "Bishop Kennedy", "Blarney", "Bleu d'Auvergne",
+            "Bleu de Gex", "Bleu de Laqueuille", "Bleu de Septmoncel",
+            "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini",
+            "Bocconcini (Australian)", "Boeren Leidenkaas", "Bonchester",
+            "Bosworth", "Bougon", "Boule Du Roves", "Boulette d'Avesnes",
+            "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois",
+            "Brebis du Puyfaucon", "Bresse Bleu", "Brick", "Brie",
+            "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", "Brin",
+            "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio",
+            "Broccio Demi-Affine", "Brousse du Rove", "Bruder Basil",
+            "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase",
+            "Button (Innes)", "Buxton Blue", "Cabecou", "Caboc", "Cabrales",
+            "Cachaille", "Caciocavallo", "Caciotta", "Caerphilly",
+            "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux",
+            "Capricorn Goat", "Capriole Banon", "Carre de l'Est",
+            "Casciotta di Urbino", "Cashel Blue", "Castellano", "Castelleno",
+            "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou",
+            "Chabichou du Poitou", "Chabis de Gatine", "Chaource", "Charolais",
+            "Chaumes", "Cheddar", "Cheddar Clothbound", "Cheshire", "Chevres",
+            "Chevrotin des Aravis", "Chontaleno", "Civray",
+            "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby",
+            "Cold Pack", "Comte", "Coolea", "Cooleney", "Coquetdale",
+            "Corleggy", "Cornish Pepper", "Cotherstone", "Cotija",
+            "Cottage Cheese", "Cottage Cheese (Australian)", "Cougar Gold",
+            "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche",
+            "Crescenza", "Croghan", "Crottin de Chavignol",
+            "Crottin du Chavignol", "Crowdie", "Crowley", "Cuajada", "Curd",
+            "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo",
+            "Danish Fontina", "Daralagjazsky", "Dauphin", "Delice des Fiouves",
+            "Denhany Dorset Drum", "Derby", "Dessertnyj Belyj", "Devon Blue",
+            "Devon Garland", "Dolcelatte", "Doolin", "Doppelrhamstufel",
+            "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra",
+            "Dunlop", "Dunsyre Blue", "Duroblando", "Durrus",
+            "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne",
+            "Esbareich", "Esrom", "Etorki", "Evansdale Farmhouse Brie",
+            "Evora De L'Alentejo", "Exmoor Blue", "Explorateur", "Feta",
+            "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis",
+            "Flor de Guia", "Flower Marie", "Folded",
+            "Folded cheese with mint", "Fondant de Brebis", "Fontainebleau",
+            "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire",
+            "Fourme de Montbrison", "Fresh Jack", "Fresh Mozzarella",
+            "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", "Friesekaas",
+            "Friesian", "Friesla", "Frinault", "Fromage a Raclette",
+            "Fromage Corse", "Fromage de Montagne de Savoie", "Fromage Frais",
+            "Fruit Cream Cheese", "Frying Cheese", "Fynbo", "Gabriel",
+            "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail",
+            "Garrotxa", "Gastanberra", "Geitost", "Gippsland Blue", "Gjetost",
+            "Gloucester", "Golden Cross", "Gorgonzola", "Gornyaltajski",
+            "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh",
+            "Greve", "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny",
+            "Halloumi", "Halloumy (Australian)", "Haloumi-Style Cheese",
+            "Harbourne Blue", "Havarti", "Heidi Gruyere", "Hereford Hop",
+            "Herrgardsost", "Herriot Farmhouse", "Herve", "Hipi Iti",
+            "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu",
+            "Isle of Mull", "Jarlsberg", "Jermi Tortes", "Jibneh Arabieh",
+            "Jindi Brie", "Jubilee Blue", "Juustoleipa", "Kadchgall", "Kaseri",
+            "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold",
+            "Klosterkaese", "Knockalara", "Kugelkase", "L'Aveyronnais",
+            "L'Ecir de l'Aubrac", "La Taupiniere", "La Vache Qui Rit",
+            "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin",
+            "Le Fium Orbo", "Le Lacandou", "Le Roule", "Leafield", "Lebbene",
+            "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer",
+            "Little Rydings", "Livarot", "Llanboidy", "Llanglofan Farmhouse",
+            "Loch Arthur Farmhouse", "Loddiswell Avondale", "Longhorn",
+            "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", "Macconais",
+            "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses",
+            "Maredsous", "Margotin", "Maribo", "Maroilles", "Mascares",
+            "Mascarpone", "Mascarpone (Australian)", "Mascarpone Torta",
+            "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)",
+            "Meyer Vintage Gouda", "Mihalic Peynir", "Milleens", "Mimolette",
+            "Mine-Gabhar", "Mini Baby Bells", "Mixte", "Molbo",
+            "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier",
+            "Morbier Cru de Montagne", "Mothais a la Feuille", "Mozzarella",
+            "Mozzarella (Australian)", "Mozzarella di Bufala",
+            "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais",
+            "Neufchatel", "Neufchatel (Australian)", "Niolo", "Nokkelost",
+            "Northumberland", "Oaxaca", "Olde York", "Olivet au Foin",
+            "Olivet Bleu", "Olivet Cendre", "Orkney Extra Mature Cheddar",
+            "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", "Oszczypek",
+            "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer",
+            "Panela", "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)",
+            "Parmigiano Reggiano", "Pas de l'Escalette", "Passendale",
+            "Pasteurized Processed", "Pate de Fromage", "Patefine Fort",
+            "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac",
+            "Pave du Berry", "Pecorino", "Pecorino in Walnut Leaves",
+            "Pecorino Romano", "Peekskill Pyramid", "Pelardon des Cevennes",
+            "Pelardon des Corbieres", "Penamellera", "Penbryn", "Pencarreg",
+            "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora",
+            "Pithtviers au Foin", "Plateau de Herve", "Plymouth Cheese",
+            "Podhalanski", "Poivre d'Ane", "Polkolbin", "Pont l'Eveque",
+            "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean",
+            "Processed Cheddar", "Provolone", "Provolone (Australian)",
+            "Pyengana Cheddar", "Pyramide", "Quark", "Quark (Australian)",
+            "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango",
+            "Queso de Murcia", "Queso del Montsec", "Queso del Tietar",
+            "Queso Fresco", "Queso Fresco (Adobera)", "Queso Iberico",
+            "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette",
+            "Ragusano", "Raschera", "Reblochon", "Red Leicester",
+            "Regal de la Dombes", "Reggianito", "Remedou", "Requeson",
+            "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata",
+            "Ridder", "Rigotte", "Rocamadour", "Rollot", "Romano",
+            "Romans Part Dieu", "Roncal", "Roquefort", "Roule",
+            "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu",
+            "Saaland Pfarr", "Saanenkaese", "Saga", "Sage Derby",
+            "Sainte Maure", "Saint-Marcellin", "Saint-Nectaire",
+            "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza",
+            "Schabzieger", "Schloss", "Selles sur Cher", "Selva", "Serat",
+            "Seriously Strong Cheddar", "Serra da Estrela", "Sharpam",
+            "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene",
+            "Smoked Gouda", "Somerset Brie", "Sonoma Jack",
+            "Sottocenare al Tartufo", "Soumaintrain", "Sourire Lozerien",
+            "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote",
+            "Sveciaost", "Swaledale", "Sweet Style Swiss", "Swiss",
+            "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea",
+            "Testouri", "Tete de Moine", "Tetilla", "Texas Goat Cheese",
+            "Tibet", "Tillamook Cheddar", "Tilsit", "Timboon Brie", "Toma",
+            "Tomme Brulee", "Tomme d'Abondance", "Tomme de Chevre",
+            "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans",
+            "Tommes", "Torta del Casar", "Toscanello", "Touree de L'Aubier",
+            "Tourmalet", "Trappe (Veritable)", "Trois Cornes De Vendee",
+            "Tronchon", "Trou du Cru", "Truffe", "Tupi", "Turunmaa",
+            "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco",
+            "Vendomois", "Vieux Corse", "Vignotte", "Vulscombe",
+            "Waimata Farmhouse Blue", "Washed Rind Cheese (Australian)",
+            "Waterloo", "Weichkaese", "Wellington", "Wensleydale",
+            "White Stilton", "Whitestone Farmhouse", "Wigmore",
+            "Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
+            "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
+            "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List14.java b/samples/ApiDemos/src/com/example/android/apis/view/List14.java
new file mode 100644
index 0000000..41eb481
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List14.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2008 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.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+import android.widget.ImageView;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import com.example.android.apis.R;
+
+/**
+ * Demonstrates how to write an efficient list adapter. The adapter used in this example binds
+ * to an ImageView and to a TextView for each row in the list.
+ *
+ * To work efficiently the adapter implemented here uses two techniques:
+ * - It reuses the convertView passed to getView() to avoid inflating View when it is not necessary
+ * - It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary
+ *
+ * The ViewHolder pattern consists in storing a data structure in the tag of the view returned by
+ * getView(). This data structures contains references to the views we want to bind data to, thus
+ * avoiding calls to findViewById() every time getView() is invoked.
+ */
+public class List14 extends ListActivity {
+
+    private static class EfficientAdapter extends BaseAdapter {
+        private LayoutInflater mInflater;
+        private Bitmap mIcon1;
+        private Bitmap mIcon2;
+
+        public EfficientAdapter(Context context) {
+            // Cache the LayoutInflate to avoid asking for a new one each time.
+            mInflater = LayoutInflater.from(context);
+
+            // Icons bound to the rows.
+            mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1);
+            mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2);
+        }
+
+        /**
+         * The number of items in the list is determined by the number of speeches
+         * in our array.
+         *
+         * @see android.widget.ListAdapter#getCount()
+         */
+        public int getCount() {
+            return DATA.length;
+        }
+
+        /**
+         * Since the data comes from an array, just returning the index is
+         * sufficent to get at the data. If we were using a more complex data
+         * structure, we would return whatever object represents one row in the
+         * list.
+         *
+         * @see android.widget.ListAdapter#getItem(int)
+         */
+        public Object getItem(int position) {
+            return position;
+        }
+
+        /**
+         * Use the array index as a unique id.
+         *
+         * @see android.widget.ListAdapter#getItemId(int)
+         */
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Make a view to hold each row.
+         *
+         * @see android.widget.ListAdapter#getView(int, android.view.View,
+         *      android.view.ViewGroup)
+         */
+        public View getView(int position, View convertView, ViewGroup parent) {
+            // A ViewHolder keeps references to children views to avoid unneccessary calls
+            // to findViewById() on each row.
+            ViewHolder holder;
+
+            // When convertView is not null, we can reuse it directly, there is no need
+            // to reinflate it. We only inflate a new View when the convertView supplied
+            // by ListView is null.
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
+
+                // Creates a ViewHolder and store references to the two children views
+                // we want to bind data to.
+                holder = new ViewHolder();
+                holder.text = (TextView) convertView.findViewById(R.id.text);
+                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
+
+                convertView.setTag(holder);
+            } else {
+                // Get the ViewHolder back to get fast access to the TextView
+                // and the ImageView.
+                holder = (ViewHolder) convertView.getTag();
+            }
+
+            // Bind the data efficiently with the holder.
+            holder.text.setText(DATA[position]);
+            holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
+
+            return convertView;
+        }
+
+        static class ViewHolder {
+            TextView text;
+            ImageView icon;
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setListAdapter(new EfficientAdapter(this));
+    }
+
+    private static final String[] DATA = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
+            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
+            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
+            "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh",
+            "Anthoriro", "Appenzell", "Aragon", "Ardi Gasna", "Ardrahan",
+            "Armenian String", "Aromes au Gene de Marc", "Asadero", "Asiago",
+            "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", "Babybel",
+            "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal",
+            "Banon", "Barry's Bay Cheddar", "Basing", "Basket Cheese",
+            "Bath Cheese", "Bavarian Bergkase", "Baylough", "Beaufort",
+            "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir",
+            "Bierkase", "Bishop Kennedy", "Blarney", "Bleu d'Auvergne",
+            "Bleu de Gex", "Bleu de Laqueuille", "Bleu de Septmoncel",
+            "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini",
+            "Bocconcini (Australian)", "Boeren Leidenkaas", "Bonchester",
+            "Bosworth", "Bougon", "Boule Du Roves", "Boulette d'Avesnes",
+            "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois",
+            "Brebis du Puyfaucon", "Bresse Bleu", "Brick", "Brie",
+            "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", "Brin",
+            "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio",
+            "Broccio Demi-Affine", "Brousse du Rove", "Bruder Basil",
+            "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase",
+            "Button (Innes)", "Buxton Blue", "Cabecou", "Caboc", "Cabrales",
+            "Cachaille", "Caciocavallo", "Caciotta", "Caerphilly",
+            "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux",
+            "Capricorn Goat", "Capriole Banon", "Carre de l'Est",
+            "Casciotta di Urbino", "Cashel Blue", "Castellano", "Castelleno",
+            "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou",
+            "Chabichou du Poitou", "Chabis de Gatine", "Chaource", "Charolais",
+            "Chaumes", "Cheddar", "Cheddar Clothbound", "Cheshire", "Chevres",
+            "Chevrotin des Aravis", "Chontaleno", "Civray",
+            "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby",
+            "Cold Pack", "Comte", "Coolea", "Cooleney", "Coquetdale",
+            "Corleggy", "Cornish Pepper", "Cotherstone", "Cotija",
+            "Cottage Cheese", "Cottage Cheese (Australian)", "Cougar Gold",
+            "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche",
+            "Crescenza", "Croghan", "Crottin de Chavignol",
+            "Crottin du Chavignol", "Crowdie", "Crowley", "Cuajada", "Curd",
+            "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo",
+            "Danish Fontina", "Daralagjazsky", "Dauphin", "Delice des Fiouves",
+            "Denhany Dorset Drum", "Derby", "Dessertnyj Belyj", "Devon Blue",
+            "Devon Garland", "Dolcelatte", "Doolin", "Doppelrhamstufel",
+            "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra",
+            "Dunlop", "Dunsyre Blue", "Duroblando", "Durrus",
+            "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne",
+            "Esbareich", "Esrom", "Etorki", "Evansdale Farmhouse Brie",
+            "Evora De L'Alentejo", "Exmoor Blue", "Explorateur", "Feta",
+            "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis",
+            "Flor de Guia", "Flower Marie", "Folded",
+            "Folded cheese with mint", "Fondant de Brebis", "Fontainebleau",
+            "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire",
+            "Fourme de Montbrison", "Fresh Jack", "Fresh Mozzarella",
+            "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", "Friesekaas",
+            "Friesian", "Friesla", "Frinault", "Fromage a Raclette",
+            "Fromage Corse", "Fromage de Montagne de Savoie", "Fromage Frais",
+            "Fruit Cream Cheese", "Frying Cheese", "Fynbo", "Gabriel",
+            "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail",
+            "Garrotxa", "Gastanberra", "Geitost", "Gippsland Blue", "Gjetost",
+            "Gloucester", "Golden Cross", "Gorgonzola", "Gornyaltajski",
+            "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh",
+            "Greve", "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny",
+            "Halloumi", "Halloumy (Australian)", "Haloumi-Style Cheese",
+            "Harbourne Blue", "Havarti", "Heidi Gruyere", "Hereford Hop",
+            "Herrgardsost", "Herriot Farmhouse", "Herve", "Hipi Iti",
+            "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu",
+            "Isle of Mull", "Jarlsberg", "Jermi Tortes", "Jibneh Arabieh",
+            "Jindi Brie", "Jubilee Blue", "Juustoleipa", "Kadchgall", "Kaseri",
+            "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold",
+            "Klosterkaese", "Knockalara", "Kugelkase", "L'Aveyronnais",
+            "L'Ecir de l'Aubrac", "La Taupiniere", "La Vache Qui Rit",
+            "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin",
+            "Le Fium Orbo", "Le Lacandou", "Le Roule", "Leafield", "Lebbene",
+            "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer",
+            "Little Rydings", "Livarot", "Llanboidy", "Llanglofan Farmhouse",
+            "Loch Arthur Farmhouse", "Loddiswell Avondale", "Longhorn",
+            "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", "Macconais",
+            "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses",
+            "Maredsous", "Margotin", "Maribo", "Maroilles", "Mascares",
+            "Mascarpone", "Mascarpone (Australian)", "Mascarpone Torta",
+            "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)",
+            "Meyer Vintage Gouda", "Mihalic Peynir", "Milleens", "Mimolette",
+            "Mine-Gabhar", "Mini Baby Bells", "Mixte", "Molbo",
+            "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier",
+            "Morbier Cru de Montagne", "Mothais a la Feuille", "Mozzarella",
+            "Mozzarella (Australian)", "Mozzarella di Bufala",
+            "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais",
+            "Neufchatel", "Neufchatel (Australian)", "Niolo", "Nokkelost",
+            "Northumberland", "Oaxaca", "Olde York", "Olivet au Foin",
+            "Olivet Bleu", "Olivet Cendre", "Orkney Extra Mature Cheddar",
+            "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", "Oszczypek",
+            "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer",
+            "Panela", "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)",
+            "Parmigiano Reggiano", "Pas de l'Escalette", "Passendale",
+            "Pasteurized Processed", "Pate de Fromage", "Patefine Fort",
+            "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac",
+            "Pave du Berry", "Pecorino", "Pecorino in Walnut Leaves",
+            "Pecorino Romano", "Peekskill Pyramid", "Pelardon des Cevennes",
+            "Pelardon des Corbieres", "Penamellera", "Penbryn", "Pencarreg",
+            "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora",
+            "Pithtviers au Foin", "Plateau de Herve", "Plymouth Cheese",
+            "Podhalanski", "Poivre d'Ane", "Polkolbin", "Pont l'Eveque",
+            "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean",
+            "Processed Cheddar", "Provolone", "Provolone (Australian)",
+            "Pyengana Cheddar", "Pyramide", "Quark", "Quark (Australian)",
+            "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango",
+            "Queso de Murcia", "Queso del Montsec", "Queso del Tietar",
+            "Queso Fresco", "Queso Fresco (Adobera)", "Queso Iberico",
+            "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette",
+            "Ragusano", "Raschera", "Reblochon", "Red Leicester",
+            "Regal de la Dombes", "Reggianito", "Remedou", "Requeson",
+            "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata",
+            "Ridder", "Rigotte", "Rocamadour", "Rollot", "Romano",
+            "Romans Part Dieu", "Roncal", "Roquefort", "Roule",
+            "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu",
+            "Saaland Pfarr", "Saanenkaese", "Saga", "Sage Derby",
+            "Sainte Maure", "Saint-Marcellin", "Saint-Nectaire",
+            "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza",
+            "Schabzieger", "Schloss", "Selles sur Cher", "Selva", "Serat",
+            "Seriously Strong Cheddar", "Serra da Estrela", "Sharpam",
+            "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene",
+            "Smoked Gouda", "Somerset Brie", "Sonoma Jack",
+            "Sottocenare al Tartufo", "Soumaintrain", "Sourire Lozerien",
+            "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote",
+            "Sveciaost", "Swaledale", "Sweet Style Swiss", "Swiss",
+            "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea",
+            "Testouri", "Tete de Moine", "Tetilla", "Texas Goat Cheese",
+            "Tibet", "Tillamook Cheddar", "Tilsit", "Timboon Brie", "Toma",
+            "Tomme Brulee", "Tomme d'Abondance", "Tomme de Chevre",
+            "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans",
+            "Tommes", "Torta del Casar", "Toscanello", "Touree de L'Aubier",
+            "Tourmalet", "Trappe (Veritable)", "Trois Cornes De Vendee",
+            "Tronchon", "Trou du Cru", "Truffe", "Tupi", "Turunmaa",
+            "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco",
+            "Vendomois", "Vieux Corse", "Vignotte", "Vulscombe",
+            "Waimata Farmhouse Blue", "Washed Rind Cheese (Australian)",
+            "Waterloo", "Weichkaese", "Wellington", "Wensleydale",
+            "White Stilton", "Whitestone Farmhouse", "Wigmore",
+            "Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
+            "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
+            "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List2.java b/samples/ApiDemos/src/com/example/android/apis/view/List2.java
new file mode 100644
index 0000000..4f37dd8
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List2.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ListActivity;
+import android.database.Cursor;
+import android.provider.Contacts.People;
+import android.os.Bundle;
+import android.widget.ListAdapter;
+import android.widget.SimpleCursorAdapter;
+
+/**
+ * A list view example where the 
+ * data comes from a cursor.
+ */
+public class List2 extends ListActivity {
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Get a cursor with all people
+        Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+        startManagingCursor(c);
+
+        ListAdapter adapter = new SimpleCursorAdapter(this, 
+                // Use a template that displays a text view
+                android.R.layout.simple_list_item_1, 
+                // Give the cursor to the list adatper
+                c, 
+                // Map the NAME column in the people database to...
+                new String[] {People.NAME} ,
+                // The "text1" view defined in the XML template
+                new int[] {android.R.id.text1}); 
+        setListAdapter(adapter);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List3.java b/samples/ApiDemos/src/com/example/android/apis/view/List3.java
new file mode 100644
index 0000000..17e59f1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List3.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+
+import android.app.ListActivity;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Contacts.Phones;
+import android.widget.ListAdapter;
+import android.widget.SimpleCursorAdapter;
+
+ /**
+ * A list view example where the 
+ * data comes from a cursor, and a
+ * SimpleCursorListAdapter is used to map each item to a two-line
+ * display.
+ */
+public class List3 extends ListActivity {
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Get a cursor with all phones
+        Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
+        startManagingCursor(c);
+        
+        // Map Cursor columns to views defined in simple_list_item_2.xml
+        ListAdapter adapter = new SimpleCursorAdapter(this,
+                android.R.layout.simple_list_item_2, c, 
+                        new String[] { Phones.NAME, Phones.NUMBER }, 
+                        new int[] { android.R.id.text1, android.R.id.text2 });
+        setListAdapter(adapter);
+    }
+  
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List4.java b/samples/ApiDemos/src/com/example/android/apis/view/List4.java
new file mode 100644
index 0000000..2bd589d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List4.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+
+/**
+ * A list view example where the data comes from a custom ListAdapter
+ */
+public class List4 extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Use our own list adapter
+        setListAdapter(new SpeechListAdapter(this));
+    }
+
+
+    /**
+     * A sample ListAdapter that presents content from arrays of speeches and
+     * text.
+     * 
+     */
+    private class SpeechListAdapter extends BaseAdapter {
+        public SpeechListAdapter(Context context) {
+            mContext = context;
+        }
+
+        /**
+         * The number of items in the list is determined by the number of speeches
+         * in our array.
+         * 
+         * @see android.widget.ListAdapter#getCount()
+         */
+        public int getCount() {
+            return mTitles.length;
+        }
+
+        /**
+         * Since the data comes from an array, just returning the index is
+         * sufficent to get at the data. If we were using a more complex data
+         * structure, we would return whatever object represents one row in the
+         * list.
+         * 
+         * @see android.widget.ListAdapter#getItem(int)
+         */
+        public Object getItem(int position) {
+            return position;
+        }
+
+        /**
+         * Use the array index as a unique id.
+         * 
+         * @see android.widget.ListAdapter#getItemId(int)
+         */
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Make a SpeechView to hold each row.
+         * 
+         * @see android.widget.ListAdapter#getView(int, android.view.View,
+         *      android.view.ViewGroup)
+         */
+        public View getView(int position, View convertView, ViewGroup parent) {
+            SpeechView sv;
+            if (convertView == null) {
+                sv = new SpeechView(mContext, mTitles[position],
+                        mDialogue[position]);
+            } else {
+                sv = (SpeechView) convertView;
+                sv.setTitle(mTitles[position]);
+                sv.setDialogue(mDialogue[position]);
+            }
+
+            return sv;
+        }
+
+        /**
+         * Remember our context so we can use it when constructing views.
+         */
+        private Context mContext;
+        
+        /**
+         * Our data, part 1.
+         */
+        private String[] mTitles = 
+        {
+                "Henry IV (1)",   
+                "Henry V",
+                "Henry VIII",       
+                "Richard II",
+                "Richard III",
+                "Merchant of Venice",  
+                "Othello",
+                "King Lear"
+        };
+        
+        /**
+         * Our data, part 2.
+         */
+        private String[] mDialogue = 
+        {
+                "So shaken as we are, so wan with care," +
+                "Find we a time for frighted peace to pant," +
+                "And breathe short-winded accents of new broils" +
+                "To be commenced in strands afar remote." +
+                "No more the thirsty entrance of this soil" +
+                "Shall daub her lips with her own children's blood;" +
+                "Nor more shall trenching war channel her fields," +
+                "Nor bruise her flowerets with the armed hoofs" +
+                "Of hostile paces: those opposed eyes," +
+                "Which, like the meteors of a troubled heaven," +
+                "All of one nature, of one substance bred," +
+                "Did lately meet in the intestine shock" +
+                "And furious close of civil butchery" +
+                "Shall now, in mutual well-beseeming ranks," +
+                "March all one way and be no more opposed" +
+                "Against acquaintance, kindred and allies:" +
+                "The edge of war, like an ill-sheathed knife," +
+                "No more shall cut his master. Therefore, friends," +
+                "As far as to the sepulchre of Christ," +
+                "Whose soldier now, under whose blessed cross" +
+                "We are impressed and engaged to fight," +
+                "Forthwith a power of English shall we levy;" +
+                "Whose arms were moulded in their mothers' womb" +
+                "To chase these pagans in those holy fields" +
+                "Over whose acres walk'd those blessed feet" +
+                "Which fourteen hundred years ago were nail'd" +
+                "For our advantage on the bitter cross." +
+                "But this our purpose now is twelve month old," +
+                "And bootless 'tis to tell you we will go:" +
+                "Therefore we meet not now. Then let me hear" +
+                "Of you, my gentle cousin Westmoreland," +
+                "What yesternight our council did decree" +
+                "In forwarding this dear expedience.",
+                
+                "Hear him but reason in divinity," + 
+                "And all-admiring with an inward wish" + 
+                "You would desire the king were made a prelate:" + 
+                "Hear him debate of commonwealth affairs," + 
+                "You would say it hath been all in all his study:" + 
+                "List his discourse of war, and you shall hear" + 
+                "A fearful battle render'd you in music:" + 
+                "Turn him to any cause of policy," + 
+                "The Gordian knot of it he will unloose," + 
+                "Familiar as his garter: that, when he speaks," + 
+                "The air, a charter'd libertine, is still," + 
+                "And the mute wonder lurketh in men's ears," + 
+                "To steal his sweet and honey'd sentences;" + 
+                "So that the art and practic part of life" + 
+                "Must be the mistress to this theoric:" + 
+                "Which is a wonder how his grace should glean it," + 
+                "Since his addiction was to courses vain," + 
+                "His companies unletter'd, rude and shallow," + 
+                "His hours fill'd up with riots, banquets, sports," + 
+                "And never noted in him any study," + 
+                "Any retirement, any sequestration" + 
+                "From open haunts and popularity.",
+
+                "I come no more to make you laugh: things now," +
+                "That bear a weighty and a serious brow," +
+                "Sad, high, and working, full of state and woe," +
+                "Such noble scenes as draw the eye to flow," +
+                "We now present. Those that can pity, here" +
+                "May, if they think it well, let fall a tear;" +
+                "The subject will deserve it. Such as give" +
+                "Their money out of hope they may believe," +
+                "May here find truth too. Those that come to see" +
+                "Only a show or two, and so agree" +
+                "The play may pass, if they be still and willing," +
+                "I'll undertake may see away their shilling" +
+                "Richly in two short hours. Only they" +
+                "That come to hear a merry bawdy play," +
+                "A noise of targets, or to see a fellow" +
+                "In a long motley coat guarded with yellow," +
+                "Will be deceived; for, gentle hearers, know," +
+                "To rank our chosen truth with such a show" +
+                "As fool and fight is, beside forfeiting" +
+                "Our own brains, and the opinion that we bring," +
+                "To make that only true we now intend," +
+                "Will leave us never an understanding friend." +
+                "Therefore, for goodness' sake, and as you are known" +
+                "The first and happiest hearers of the town," +
+                "Be sad, as we would make ye: think ye see" +
+                "The very persons of our noble story" +
+                "As they were living; think you see them great," +
+                "And follow'd with the general throng and sweat" +
+                "Of thousand friends; then in a moment, see" +
+                "How soon this mightiness meets misery:" +
+                "And, if you can be merry then, I'll say" +
+                "A man may weep upon his wedding-day.",
+                
+                "First, heaven be the record to my speech!" + 
+                "In the devotion of a subject's love," + 
+                "Tendering the precious safety of my prince," + 
+                "And free from other misbegotten hate," + 
+                "Come I appellant to this princely presence." + 
+                "Now, Thomas Mowbray, do I turn to thee," + 
+                "And mark my greeting well; for what I speak" + 
+                "My body shall make good upon this earth," + 
+                "Or my divine soul answer it in heaven." + 
+                "Thou art a traitor and a miscreant," + 
+                "Too good to be so and too bad to live," + 
+                "Since the more fair and crystal is the sky," + 
+                "The uglier seem the clouds that in it fly." + 
+                "Once more, the more to aggravate the note," + 
+                "With a foul traitor's name stuff I thy throat;" + 
+                "And wish, so please my sovereign, ere I move," + 
+                "What my tongue speaks my right drawn sword may prove.",
+                
+                "Now is the winter of our discontent" + 
+                "Made glorious summer by this sun of York;" + 
+                "And all the clouds that lour'd upon our house" + 
+                "In the deep bosom of the ocean buried." + 
+                "Now are our brows bound with victorious wreaths;" + 
+                "Our bruised arms hung up for monuments;" + 
+                "Our stern alarums changed to merry meetings," + 
+                "Our dreadful marches to delightful measures." + 
+                "Grim-visaged war hath smooth'd his wrinkled front;" + 
+                "And now, instead of mounting barded steeds" + 
+                "To fright the souls of fearful adversaries," + 
+                "He capers nimbly in a lady's chamber" + 
+                "To the lascivious pleasing of a lute." + 
+                "But I, that am not shaped for sportive tricks," + 
+                "Nor made to court an amorous looking-glass;" + 
+                "I, that am rudely stamp'd, and want love's majesty" + 
+                "To strut before a wanton ambling nymph;" + 
+                "I, that am curtail'd of this fair proportion," + 
+                "Cheated of feature by dissembling nature," + 
+                "Deformed, unfinish'd, sent before my time" + 
+                "Into this breathing world, scarce half made up," + 
+                "And that so lamely and unfashionable" + 
+                "That dogs bark at me as I halt by them;" + 
+                "Why, I, in this weak piping time of peace," + 
+                "Have no delight to pass away the time," + 
+                "Unless to spy my shadow in the sun" + 
+                "And descant on mine own deformity:" + 
+                "And therefore, since I cannot prove a lover," + 
+                "To entertain these fair well-spoken days," + 
+                "I am determined to prove a villain" + 
+                "And hate the idle pleasures of these days." + 
+                "Plots have I laid, inductions dangerous," + 
+                "By drunken prophecies, libels and dreams," + 
+                "To set my brother Clarence and the king" + 
+                "In deadly hate the one against the other:" + 
+                "And if King Edward be as true and just" + 
+                "As I am subtle, false and treacherous," + 
+                "This day should Clarence closely be mew'd up," + 
+                "About a prophecy, which says that 'G'" + 
+                "Of Edward's heirs the murderer shall be." + 
+                "Dive, thoughts, down to my soul: here" + 
+                "Clarence comes.",
+                
+                "To bait fish withal: if it will feed nothing else," + 
+                "it will feed my revenge. He hath disgraced me, and" + 
+                "hindered me half a million; laughed at my losses," + 
+                "mocked at my gains, scorned my nation, thwarted my" + 
+                "bargains, cooled my friends, heated mine" + 
+                "enemies; and what's his reason? I am a Jew. Hath" + 
+                "not a Jew eyes? hath not a Jew hands, organs," + 
+                "dimensions, senses, affections, passions? fed with" + 
+                "the same food, hurt with the same weapons, subject" + 
+                "to the same diseases, healed by the same means," + 
+                "warmed and cooled by the same winter and summer, as" + 
+                "a Christian is? If you prick us, do we not bleed?" + 
+                "if you tickle us, do we not laugh? if you poison" + 
+                "us, do we not die? and if you wrong us, shall we not" + 
+                "revenge? If we are like you in the rest, we will" + 
+                "resemble you in that. If a Jew wrong a Christian," + 
+                "what is his humility? Revenge. If a Christian" + 
+                "wrong a Jew, what should his sufferance be by" + 
+                "Christian example? Why, revenge. The villany you" + 
+                "teach me, I will execute, and it shall go hard but I" + 
+                "will better the instruction.",
+                
+                "Virtue! a fig! 'tis in ourselves that we are thus" + 
+                "or thus. Our bodies are our gardens, to the which" + 
+                "our wills are gardeners: so that if we will plant" + 
+                "nettles, or sow lettuce, set hyssop and weed up" + 
+                "thyme, supply it with one gender of herbs, or" + 
+                "distract it with many, either to have it sterile" + 
+                "with idleness, or manured with industry, why, the" + 
+                "power and corrigible authority of this lies in our" + 
+                "wills. If the balance of our lives had not one" + 
+                "scale of reason to poise another of sensuality, the" + 
+                "blood and baseness of our natures would conduct us" + 
+                "to most preposterous conclusions: but we have" + 
+                "reason to cool our raging motions, our carnal" + 
+                "stings, our unbitted lusts, whereof I take this that" + 
+                "you call love to be a sect or scion.",
+
+                "Blow, winds, and crack your cheeks! rage! blow!" + 
+                "You cataracts and hurricanoes, spout" + 
+                "Till you have drench'd our steeples, drown'd the cocks!" + 
+                "You sulphurous and thought-executing fires," + 
+                "Vaunt-couriers to oak-cleaving thunderbolts," + 
+                "Singe my white head! And thou, all-shaking thunder," + 
+                "Smite flat the thick rotundity o' the world!" + 
+                "Crack nature's moulds, an germens spill at once," + 
+                "That make ingrateful man!"
+        };
+    }
+    
+    /**
+     * We will use a SpeechView to display each speech. It's just a LinearLayout
+     * with two text fields.
+     *
+     */
+    private class SpeechView extends LinearLayout {
+        public SpeechView(Context context, String title, String words) {
+            super(context);
+
+            this.setOrientation(VERTICAL);
+
+            // Here we build the child views in code. They could also have
+            // been specified in an XML file.
+
+            mTitle = new TextView(context);
+            mTitle.setText(title);
+            addView(mTitle, new LinearLayout.LayoutParams(
+                    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+
+            mDialogue = new TextView(context);
+            mDialogue.setText(words);
+            addView(mDialogue, new LinearLayout.LayoutParams(
+                    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+        }
+
+        /**
+         * Convenience method to set the title of a SpeechView
+         */
+        public void setTitle(String title) {
+            mTitle.setText(title);
+        }
+
+        /**
+         * Convenience method to set the dialogue of a SpeechView
+         */
+        public void setDialogue(String words) {
+            mDialogue.setText(words);
+        }
+
+        private TextView mTitle;
+        private TextView mDialogue;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List5.java b/samples/ApiDemos/src/com/example/android/apis/view/List5.java
new file mode 100644
index 0000000..72a8b82
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List5.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+
+/**
+ * A list view example with separators.
+ */
+public class List5 extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setListAdapter(new MyListAdapter(this));
+    }
+
+    private class MyListAdapter extends BaseAdapter {
+        public MyListAdapter(Context context) {
+            mContext = context;
+        }
+
+        public int getCount() {
+            return mStrings.length;
+        }
+
+        public boolean areAllItemsEnabled() {
+            return false;
+        }
+
+        public boolean isEnabled(int position) {
+            return !mStrings[position].startsWith("-");
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            TextView tv;
+            if (convertView == null) {
+                tv = (TextView) LayoutInflater.from(mContext).inflate(
+                        android.R.layout.simple_expandable_list_item_1, parent, false);
+            } else {
+                tv = (TextView) convertView;
+            }
+            tv.setText(mStrings[position]);
+            return tv;
+        }
+
+        private Context mContext;
+    }
+    
+    private String[] mStrings = {
+            "----------",
+            "----------",
+            "Abbaye de Belloc",
+            "Abbaye du Mont des Cats",
+            "Abertam",
+            "----------",
+            "Abondance",
+            "----------",
+            "Ackawi",
+            "Acorn",
+            "Adelost",
+            "Affidelice au Chablis",
+            "Afuega'l Pitu",
+            "Airag",
+            "----------",
+            "Airedale",
+            "Aisy Cendre",
+            "----------",
+            "Allgauer Emmentaler",
+            "Alverca",
+            "Ambert",
+            "American Cheese",
+            "Ami du Chambertin",
+            "----------",
+            "----------",
+            "Anejo Enchilado",
+            "Anneau du Vic-Bilh",
+            "Anthoriro",
+            "----------",
+            "----------"
+    };
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List6.java b/samples/ApiDemos/src/com/example/android/apis/view/List6.java
new file mode 100644
index 0000000..9bb5b14
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List6.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+
+/**
+ * A list view example where the 
+ * data comes from a custom
+ * ListAdapter
+ */
+public class List6 extends ListActivity 
+{
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        
+        // Use our own list adapter
+        setListAdapter(new SpeechListAdapter(this));
+    }
+        
+    
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) 
+    {    
+       ((SpeechListAdapter)getListAdapter()).toggle(position);
+    }
+    
+    /**
+     * A sample ListAdapter that presents content
+     * from arrays of speeches and text.
+     *
+     */
+    private class SpeechListAdapter extends BaseAdapter {
+        public SpeechListAdapter(Context context)
+        {
+            mContext = context;
+        }
+
+        
+        /**
+         * The number of items in the list is determined by the number of speeches
+         * in our array.
+         * 
+         * @see android.widget.ListAdapter#getCount()
+         */
+        public int getCount() {
+            return mTitles.length;
+        }
+
+        /**
+         * Since the data comes from an array, just returning
+         * the index is sufficent to get at the data. If we
+         * were using a more complex data structure, we
+         * would return whatever object represents one 
+         * row in the list.
+         * 
+         * @see android.widget.ListAdapter#getItem(int)
+         */
+        public Object getItem(int position) {
+            return position;
+        }
+
+        /**
+         * Use the array index as a unique id.
+         * @see android.widget.ListAdapter#getItemId(int)
+         */
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Make a SpeechView to hold each row.
+         * @see android.widget.ListAdapter#getView(int, android.view.View, android.view.ViewGroup)
+         */
+        public View getView(int position, View convertView, ViewGroup parent) {
+            SpeechView sv;
+            if (convertView == null) {
+                sv = new SpeechView(mContext, mTitles[position], mDialogue[position], mExpanded[position]);
+            } else {
+                sv = (SpeechView)convertView;
+                sv.setTitle(mTitles[position]);
+                sv.setDialogue(mDialogue[position]);
+                sv.setExpanded(mExpanded[position]);
+            }
+            
+            return sv;
+        }
+
+        public void toggle(int position) {
+            mExpanded[position] = !mExpanded[position];
+            notifyDataSetChanged();
+        }
+        
+        /**
+         * Remember our context so we can use it when constructing views.
+         */
+        private Context mContext;
+        
+        /**
+         * Our data, part 1.
+         */
+        private String[] mTitles = 
+        {
+                "Henry IV (1)",   
+                "Henry V",
+                "Henry VIII",       
+                "Richard II",
+                "Richard III",
+                "Merchant of Venice",  
+                "Othello",
+                "King Lear"
+        };
+        
+        /**
+         * Our data, part 2.
+         */
+        private String[] mDialogue = 
+        {
+                "So shaken as we are, so wan with care," +
+                "Find we a time for frighted peace to pant," +
+                "And breathe short-winded accents of new broils" +
+                "To be commenced in strands afar remote." +
+                "No more the thirsty entrance of this soil" +
+                "Shall daub her lips with her own children's blood;" +
+                "Nor more shall trenching war channel her fields," +
+                "Nor bruise her flowerets with the armed hoofs" +
+                "Of hostile paces: those opposed eyes," +
+                "Which, like the meteors of a troubled heaven," +
+                "All of one nature, of one substance bred," +
+                "Did lately meet in the intestine shock" +
+                "And furious close of civil butchery" +
+                "Shall now, in mutual well-beseeming ranks," +
+                "March all one way and be no more opposed" +
+                "Against acquaintance, kindred and allies:" +
+                "The edge of war, like an ill-sheathed knife," +
+                "No more shall cut his master. Therefore, friends," +
+                "As far as to the sepulchre of Christ," +
+                "Whose soldier now, under whose blessed cross" +
+                "We are impressed and engaged to fight," +
+                "Forthwith a power of English shall we levy;" +
+                "Whose arms were moulded in their mothers' womb" +
+                "To chase these pagans in those holy fields" +
+                "Over whose acres walk'd those blessed feet" +
+                "Which fourteen hundred years ago were nail'd" +
+                "For our advantage on the bitter cross." +
+                "But this our purpose now is twelve month old," +
+                "And bootless 'tis to tell you we will go:" +
+                "Therefore we meet not now. Then let me hear" +
+                "Of you, my gentle cousin Westmoreland," +
+                "What yesternight our council did decree" +
+                "In forwarding this dear expedience.",
+                
+                "Hear him but reason in divinity," + 
+                "And all-admiring with an inward wish" + 
+                "You would desire the king were made a prelate:" + 
+                "Hear him debate of commonwealth affairs," + 
+                "You would say it hath been all in all his study:" + 
+                "List his discourse of war, and you shall hear" + 
+                "A fearful battle render'd you in music:" + 
+                "Turn him to any cause of policy," + 
+                "The Gordian knot of it he will unloose," + 
+                "Familiar as his garter: that, when he speaks," + 
+                "The air, a charter'd libertine, is still," + 
+                "And the mute wonder lurketh in men's ears," + 
+                "To steal his sweet and honey'd sentences;" + 
+                "So that the art and practic part of life" + 
+                "Must be the mistress to this theoric:" + 
+                "Which is a wonder how his grace should glean it," + 
+                "Since his addiction was to courses vain," + 
+                "His companies unletter'd, rude and shallow," + 
+                "His hours fill'd up with riots, banquets, sports," + 
+                "And never noted in him any study," + 
+                "Any retirement, any sequestration" + 
+                "From open haunts and popularity.",
+
+                "I come no more to make you laugh: things now," +
+                "That bear a weighty and a serious brow," +
+                "Sad, high, and working, full of state and woe," +
+                "Such noble scenes as draw the eye to flow," +
+                "We now present. Those that can pity, here" +
+                "May, if they think it well, let fall a tear;" +
+                "The subject will deserve it. Such as give" +
+                "Their money out of hope they may believe," +
+                "May here find truth too. Those that come to see" +
+                "Only a show or two, and so agree" +
+                "The play may pass, if they be still and willing," +
+                "I'll undertake may see away their shilling" +
+                "Richly in two short hours. Only they" +
+                "That come to hear a merry bawdy play," +
+                "A noise of targets, or to see a fellow" +
+                "In a long motley coat guarded with yellow," +
+                "Will be deceived; for, gentle hearers, know," +
+                "To rank our chosen truth with such a show" +
+                "As fool and fight is, beside forfeiting" +
+                "Our own brains, and the opinion that we bring," +
+                "To make that only true we now intend," +
+                "Will leave us never an understanding friend." +
+                "Therefore, for goodness' sake, and as you are known" +
+                "The first and happiest hearers of the town," +
+                "Be sad, as we would make ye: think ye see" +
+                "The very persons of our noble story" +
+                "As they were living; think you see them great," +
+                "And follow'd with the general throng and sweat" +
+                "Of thousand friends; then in a moment, see" +
+                "How soon this mightiness meets misery:" +
+                "And, if you can be merry then, I'll say" +
+                "A man may weep upon his wedding-day.",
+                
+                "First, heaven be the record to my speech!" + 
+                "In the devotion of a subject's love," + 
+                "Tendering the precious safety of my prince," + 
+                "And free from other misbegotten hate," + 
+                "Come I appellant to this princely presence." + 
+                "Now, Thomas Mowbray, do I turn to thee," + 
+                "And mark my greeting well; for what I speak" + 
+                "My body shall make good upon this earth," + 
+                "Or my divine soul answer it in heaven." + 
+                "Thou art a traitor and a miscreant," + 
+                "Too good to be so and too bad to live," + 
+                "Since the more fair and crystal is the sky," + 
+                "The uglier seem the clouds that in it fly." + 
+                "Once more, the more to aggravate the note," + 
+                "With a foul traitor's name stuff I thy throat;" + 
+                "And wish, so please my sovereign, ere I move," + 
+                "What my tongue speaks my right drawn sword may prove.",
+                
+                "Now is the winter of our discontent" + 
+                "Made glorious summer by this sun of York;" + 
+                "And all the clouds that lour'd upon our house" + 
+                "In the deep bosom of the ocean buried." + 
+                "Now are our brows bound with victorious wreaths;" + 
+                "Our bruised arms hung up for monuments;" + 
+                "Our stern alarums changed to merry meetings," + 
+                "Our dreadful marches to delightful measures." + 
+                "Grim-visaged war hath smooth'd his wrinkled front;" + 
+                "And now, instead of mounting barded steeds" + 
+                "To fright the souls of fearful adversaries," + 
+                "He capers nimbly in a lady's chamber" + 
+                "To the lascivious pleasing of a lute." + 
+                "But I, that am not shaped for sportive tricks," + 
+                "Nor made to court an amorous looking-glass;" + 
+                "I, that am rudely stamp'd, and want love's majesty" + 
+                "To strut before a wanton ambling nymph;" + 
+                "I, that am curtail'd of this fair proportion," + 
+                "Cheated of feature by dissembling nature," + 
+                "Deformed, unfinish'd, sent before my time" + 
+                "Into this breathing world, scarce half made up," + 
+                "And that so lamely and unfashionable" + 
+                "That dogs bark at me as I halt by them;" + 
+                "Why, I, in this weak piping time of peace," + 
+                "Have no delight to pass away the time," + 
+                "Unless to spy my shadow in the sun" + 
+                "And descant on mine own deformity:" + 
+                "And therefore, since I cannot prove a lover," + 
+                "To entertain these fair well-spoken days," + 
+                "I am determined to prove a villain" + 
+                "And hate the idle pleasures of these days." + 
+                "Plots have I laid, inductions dangerous," + 
+                "By drunken prophecies, libels and dreams," + 
+                "To set my brother Clarence and the king" + 
+                "In deadly hate the one against the other:" + 
+                "And if King Edward be as true and just" + 
+                "As I am subtle, false and treacherous," + 
+                "This day should Clarence closely be mew'd up," + 
+                "About a prophecy, which says that 'G'" + 
+                "Of Edward's heirs the murderer shall be." + 
+                "Dive, thoughts, down to my soul: here" + 
+                "Clarence comes.",
+                
+                "To bait fish withal: if it will feed nothing else," + 
+                "it will feed my revenge. He hath disgraced me, and" + 
+                "hindered me half a million; laughed at my losses," + 
+                "mocked at my gains, scorned my nation, thwarted my" + 
+                "bargains, cooled my friends, heated mine" + 
+                "enemies; and what's his reason? I am a Jew. Hath" + 
+                "not a Jew eyes? hath not a Jew hands, organs," + 
+                "dimensions, senses, affections, passions? fed with" + 
+                "the same food, hurt with the same weapons, subject" + 
+                "to the same diseases, healed by the same means," + 
+                "warmed and cooled by the same winter and summer, as" + 
+                "a Christian is? If you prick us, do we not bleed?" + 
+                "if you tickle us, do we not laugh? if you poison" + 
+                "us, do we not die? and if you wrong us, shall we not" + 
+                "revenge? If we are like you in the rest, we will" + 
+                "resemble you in that. If a Jew wrong a Christian," + 
+                "what is his humility? Revenge. If a Christian" + 
+                "wrong a Jew, what should his sufferance be by" + 
+                "Christian example? Why, revenge. The villany you" + 
+                "teach me, I will execute, and it shall go hard but I" + 
+                "will better the instruction.",
+                
+                "Virtue! a fig! 'tis in ourselves that we are thus" + 
+                "or thus. Our bodies are our gardens, to the which" + 
+                "our wills are gardeners: so that if we will plant" + 
+                "nettles, or sow lettuce, set hyssop and weed up" + 
+                "thyme, supply it with one gender of herbs, or" + 
+                "distract it with many, either to have it sterile" + 
+                "with idleness, or manured with industry, why, the" + 
+                "power and corrigible authority of this lies in our" + 
+                "wills. If the balance of our lives had not one" + 
+                "scale of reason to poise another of sensuality, the" + 
+                "blood and baseness of our natures would conduct us" + 
+                "to most preposterous conclusions: but we have" + 
+                "reason to cool our raging motions, our carnal" + 
+                "stings, our unbitted lusts, whereof I take this that" + 
+                "you call love to be a sect or scion.",
+
+                "Blow, winds, and crack your cheeks! rage! blow!" + 
+                "You cataracts and hurricanoes, spout" + 
+                "Till you have drench'd our steeples, drown'd the cocks!" + 
+                "You sulphurous and thought-executing fires," + 
+                "Vaunt-couriers to oak-cleaving thunderbolts," + 
+                "Singe my white head! And thou, all-shaking thunder," + 
+                "Smite flat the thick rotundity o' the world!" + 
+                "Crack nature's moulds, an germens spill at once," + 
+                "That make ingrateful man!"
+        };
+        
+        /**
+         * Our data, part 3.
+         */
+        private boolean[] mExpanded = 
+        {
+                false,
+                false,
+                false,
+                false,
+                false,
+                false,
+                false,
+                false   
+        };
+    }
+    
+    /**
+     * We will use a SpeechView to display each speech. It's just a LinearLayout
+     * with two text fields.
+     *
+     */
+    private class SpeechView extends LinearLayout {
+        public SpeechView(Context context, String title, String dialogue, boolean expanded) {
+            super(context);
+            
+            this.setOrientation(VERTICAL);
+            
+            // Here we build the child views in code. They could also have
+            // been specified in an XML file.
+            
+            mTitle = new TextView(context);
+            mTitle.setText(title);
+            addView(mTitle, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+            
+            mDialogue = new TextView(context);
+            mDialogue.setText(dialogue);
+            addView(mDialogue, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+            
+            mDialogue.setVisibility(expanded ? VISIBLE : GONE);
+        }
+        
+        /**
+         * Convenience method to set the title of a SpeechView
+         */
+        public void setTitle(String title) {
+            mTitle.setText(title);
+        }
+        
+        /**
+         * Convenience method to set the dialogue of a SpeechView
+         */
+        public void setDialogue(String words) {
+            mDialogue.setText(words);
+        }
+        
+        /**
+         * Convenience method to expand or hide the dialogue
+         */
+        public void setExpanded(boolean expanded) {
+            mDialogue.setVisibility(expanded ? VISIBLE : GONE);
+        }
+        
+        private TextView mTitle;
+        private TextView mDialogue;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List7.java b/samples/ApiDemos/src/com/example/android/apis/view/List7.java
new file mode 100644
index 0000000..d44ed56
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List7.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+
+import android.app.ListActivity;
+import android.database.Cursor;
+import android.provider.Contacts.People;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ListAdapter;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+
+/**
+ * A list view example where the data comes from a cursor.
+ */
+public class List7 extends ListActivity implements OnItemSelectedListener {
+    private static String[] PROJECTION = new String[] {
+        People._ID, People.NAME, People.NUMBER
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.list_7);
+        mPhone = (TextView) findViewById(R.id.phone);
+        getListView().setOnItemSelectedListener(this);
+
+        // Get a cursor with all people
+        Cursor c = getContentResolver().query(People.CONTENT_URI, PROJECTION, null, null, null);
+        startManagingCursor(c);
+        mPhoneColumnIndex = c.getColumnIndex(People.NUMBER);
+
+        ListAdapter adapter = new SimpleCursorAdapter(this,
+                android.R.layout.simple_list_item_1, // Use a template
+                                                        // that displays a
+                                                        // text view
+                c, // Give the cursor to the list adatper
+                new String[] {People.NAME}, // Map the NAME column in the
+                                            // people database to...
+                new int[] {android.R.id.text1}); // The "text1" view defined in
+                                            // the XML template
+        setListAdapter(adapter);
+    }
+
+    public void onItemSelected(AdapterView parent, View v, int position, long id) {
+        if (position >= 0) {
+            Cursor c = (Cursor) parent.getItemAtPosition(position);
+            mPhone.setText(c.getString(mPhoneColumnIndex));
+        }
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+        mPhone.setText(R.string.list_7_nothing);
+
+    }
+
+    private int mPhoneColumnIndex;
+    private TextView mPhone;
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List8.java b/samples/ApiDemos/src/com/example/android/apis/view/List8.java
new file mode 100644
index 0000000..1a54aa7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List8.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.AbsListView;
+
+import java.util.ArrayList;
+
+
+/**
+ * A list view that demonstrates the use of setEmptyView. This example alos uses
+ * a custom layout file that adds some extra buttons to the screen.
+ */
+public class List8 extends ListActivity {
+
+    PhotoAdapter mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Use a custom layout file
+        setContentView(R.layout.list_8);
+        
+        // Tell the list view which view to display when the list is empty
+        getListView().setEmptyView(findViewById(R.id.empty));
+        
+        // Set up our adapter
+        mAdapter = new PhotoAdapter(this);
+        setListAdapter(mAdapter);
+        
+        // Wire up the clear button to remove all photos
+        Button clear = (Button) findViewById(R.id.clear);
+        clear.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                mAdapter.clearPhotos();
+            } });
+        
+        // Wire up the add button to add a new photo
+        Button add = (Button) findViewById(R.id.add);
+        add.setOnClickListener(new View.OnClickListener() {
+
+            public void onClick(View v) {
+                mAdapter.addPhotos();
+            } });
+    }
+
+    /**
+     * A simple adapter which maintains an ArrayList of photo resource Ids. 
+     * Each photo is displayed as an image. This adapter supports clearing the
+     * list of photos and adding a new photo.
+     *
+     */
+    public class PhotoAdapter extends BaseAdapter {
+
+        private Integer[] mPhotoPool = {
+                R.drawable.sample_thumb_0, R.drawable.sample_thumb_1, R.drawable.sample_thumb_2,
+                R.drawable.sample_thumb_3, R.drawable.sample_thumb_4, R.drawable.sample_thumb_5,
+                R.drawable.sample_thumb_6, R.drawable.sample_thumb_7};
+
+        private ArrayList<Integer> mPhotos = new ArrayList<Integer>();
+        
+        public PhotoAdapter(Context c) {
+            mContext = c;
+        }
+
+        public int getCount() {
+            return mPhotos.size();
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            // Make an ImageView to show a photo
+            ImageView i = new ImageView(mContext);
+
+            i.setImageResource(mPhotos.get(position));
+            i.setAdjustViewBounds(true);
+            i.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
+                    LayoutParams.WRAP_CONTENT));
+            // Give it a nice background
+            i.setBackgroundResource(R.drawable.picture_frame);
+            return i;
+        }
+
+        private Context mContext;
+
+        public void clearPhotos() {
+            mPhotos.clear();
+            notifyDataSetChanged();
+        }
+        
+        public void addPhotos() {
+            int whichPhoto = (int)Math.round(Math.random() * (mPhotoPool.length - 1));
+            int newPhoto = mPhotoPool[whichPhoto];
+            mPhotos.add(newPhoto);
+            notifyDataSetChanged();
+        }
+
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List9.java b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
new file mode 100644
index 0000000..15b3cc1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.LayoutInflater;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.AbsListView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+
+/**
+ * Another variation of the list of cheeses. In this case, we use
+ * {@link AbsListView#setOnScrollListener(AbsListView.OnScrollListener) 
+ * AbsListView#setOnItemScrollListener(AbsListView.OnItemScrollListener)} to display the
+ * first letter of the visible range of cheeses.
+ */
+public class List9 extends ListActivity implements ListView.OnScrollListener {
+
+    private final class RemoveWindow implements Runnable {
+        public void run() {
+            removeWindow();
+        }
+    }
+
+    private RemoveWindow mRemoveWindow = new RemoveWindow();
+    Handler mHandler = new Handler();
+    private WindowManager mWindowManager;
+    private TextView mDialogText;
+    private boolean mShowing;
+    private boolean mReady;
+    private char mPrevLetter = Character.MIN_VALUE;
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mWindowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
+        
+        // Use an existing ListAdapter that will map an array
+        // of strings to TextViews
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mStrings));
+        
+        getListView().setOnScrollListener(this);
+        
+        LayoutInflater inflate = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        
+        mDialogText = (TextView) inflate.inflate(R.layout.list_position, null);
+        mDialogText.setVisibility(View.INVISIBLE);
+        
+        mHandler.post(new Runnable() {
+
+            public void run() {
+                mReady = true;
+                WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
+                        WindowManager.LayoutParams.TYPE_APPLICATION,
+                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                        PixelFormat.TRANSLUCENT);
+                mWindowManager.addView(mDialogText, lp);
+            }});
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mReady = true;
+    }
+
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        removeWindow();
+        mReady = false;
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mWindowManager.removeView(mDialogText);
+        mReady = false;
+    }
+
+    
+   
+    
+    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+        int lastItem = firstVisibleItem + visibleItemCount - 1;
+        if (mReady) {
+            char firstLetter = mStrings[firstVisibleItem].charAt(0);
+            
+            if (!mShowing && firstLetter != mPrevLetter) {
+
+                mShowing = true;
+                mDialogText.setVisibility(View.VISIBLE);
+               
+
+            }
+            mDialogText.setText(((Character)firstLetter).toString());
+            mHandler.removeCallbacks(mRemoveWindow);
+            mHandler.postDelayed(mRemoveWindow, 3000);
+            mPrevLetter = firstLetter;
+        }
+    }
+    
+
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+    }
+    
+    
+    private void removeWindow() {
+        if (mShowing) {
+            mShowing = false;
+            mDialogText.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    private String[] mStrings = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
+            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
+            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
+            "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh",
+            "Anthoriro", "Appenzell", "Aragon", "Ardi Gasna", "Ardrahan",
+            "Armenian String", "Aromes au Gene de Marc", "Asadero", "Asiago",
+            "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", "Babybel",
+            "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal",
+            "Banon", "Barry's Bay Cheddar", "Basing", "Basket Cheese",
+            "Bath Cheese", "Bavarian Bergkase", "Baylough", "Beaufort",
+            "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir",
+            "Bierkase", "Bishop Kennedy", "Blarney", "Bleu d'Auvergne",
+            "Bleu de Gex", "Bleu de Laqueuille", "Bleu de Septmoncel",
+            "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini",
+            "Bocconcini (Australian)", "Boeren Leidenkaas", "Bonchester",
+            "Bosworth", "Bougon", "Boule Du Roves", "Boulette d'Avesnes",
+            "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois",
+            "Brebis du Puyfaucon", "Bresse Bleu", "Brick", "Brie",
+            "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", "Brin",
+            "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio",
+            "Broccio Demi-Affine", "Brousse du Rove", "Bruder Basil",
+            "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase",
+            "Button (Innes)", "Buxton Blue", "Cabecou", "Caboc", "Cabrales",
+            "Cachaille", "Caciocavallo", "Caciotta", "Caerphilly",
+            "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux",
+            "Capricorn Goat", "Capriole Banon", "Carre de l'Est",
+            "Casciotta di Urbino", "Cashel Blue", "Castellano", "Castelleno",
+            "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou",
+            "Chabichou du Poitou", "Chabis de Gatine", "Chaource", "Charolais",
+            "Chaumes", "Cheddar", "Cheddar Clothbound", "Cheshire", "Chevres",
+            "Chevrotin des Aravis", "Chontaleno", "Civray",
+            "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby",
+            "Cold Pack", "Comte", "Coolea", "Cooleney", "Coquetdale",
+            "Corleggy", "Cornish Pepper", "Cotherstone", "Cotija",
+            "Cottage Cheese", "Cottage Cheese (Australian)", "Cougar Gold",
+            "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche",
+            "Crescenza", "Croghan", "Crottin de Chavignol",
+            "Crottin du Chavignol", "Crowdie", "Crowley", "Cuajada", "Curd",
+            "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo",
+            "Danish Fontina", "Daralagjazsky", "Dauphin", "Delice des Fiouves",
+            "Denhany Dorset Drum", "Derby", "Dessertnyj Belyj", "Devon Blue",
+            "Devon Garland", "Dolcelatte", "Doolin", "Doppelrhamstufel",
+            "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra",
+            "Dunlop", "Dunsyre Blue", "Duroblando", "Durrus",
+            "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne",
+            "Esbareich", "Esrom", "Etorki", "Evansdale Farmhouse Brie",
+            "Evora De L'Alentejo", "Exmoor Blue", "Explorateur", "Feta",
+            "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis",
+            "Flor de Guia", "Flower Marie", "Folded",
+            "Folded cheese with mint", "Fondant de Brebis", "Fontainebleau",
+            "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire",
+            "Fourme de Montbrison", "Fresh Jack", "Fresh Mozzarella",
+            "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", "Friesekaas",
+            "Friesian", "Friesla", "Frinault", "Fromage a Raclette",
+            "Fromage Corse", "Fromage de Montagne de Savoie", "Fromage Frais",
+            "Fruit Cream Cheese", "Frying Cheese", "Fynbo", "Gabriel",
+            "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail",
+            "Garrotxa", "Gastanberra", "Geitost", "Gippsland Blue", "Gjetost",
+            "Gloucester", "Golden Cross", "Gorgonzola", "Gornyaltajski",
+            "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh",
+            "Greve", "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny",
+            "Halloumi", "Halloumy (Australian)", "Haloumi-Style Cheese",
+            "Harbourne Blue", "Havarti", "Heidi Gruyere", "Hereford Hop",
+            "Herrgardsost", "Herriot Farmhouse", "Herve", "Hipi Iti",
+            "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu",
+            "Isle of Mull", "Jarlsberg", "Jermi Tortes", "Jibneh Arabieh",
+            "Jindi Brie", "Jubilee Blue", "Juustoleipa", "Kadchgall", "Kaseri",
+            "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold",
+            "Klosterkaese", "Knockalara", "Kugelkase", "L'Aveyronnais",
+            "L'Ecir de l'Aubrac", "La Taupiniere", "La Vache Qui Rit",
+            "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin",
+            "Le Fium Orbo", "Le Lacandou", "Le Roule", "Leafield", "Lebbene",
+            "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer",
+            "Little Rydings", "Livarot", "Llanboidy", "Llanglofan Farmhouse",
+            "Loch Arthur Farmhouse", "Loddiswell Avondale", "Longhorn",
+            "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", "Macconais",
+            "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses",
+            "Maredsous", "Margotin", "Maribo", "Maroilles", "Mascares",
+            "Mascarpone", "Mascarpone (Australian)", "Mascarpone Torta",
+            "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)",
+            "Meyer Vintage Gouda", "Mihalic Peynir", "Milleens", "Mimolette",
+            "Mine-Gabhar", "Mini Baby Bells", "Mixte", "Molbo",
+            "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier",
+            "Morbier Cru de Montagne", "Mothais a la Feuille", "Mozzarella",
+            "Mozzarella (Australian)", "Mozzarella di Bufala",
+            "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais",
+            "Neufchatel", "Neufchatel (Australian)", "Niolo", "Nokkelost",
+            "Northumberland", "Oaxaca", "Olde York", "Olivet au Foin",
+            "Olivet Bleu", "Olivet Cendre", "Orkney Extra Mature Cheddar",
+            "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", "Oszczypek",
+            "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer",
+            "Panela", "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)",
+            "Parmigiano Reggiano", "Pas de l'Escalette", "Passendale",
+            "Pasteurized Processed", "Pate de Fromage", "Patefine Fort",
+            "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac",
+            "Pave du Berry", "Pecorino", "Pecorino in Walnut Leaves",
+            "Pecorino Romano", "Peekskill Pyramid", "Pelardon des Cevennes",
+            "Pelardon des Corbieres", "Penamellera", "Penbryn", "Pencarreg",
+            "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora",
+            "Pithtviers au Foin", "Plateau de Herve", "Plymouth Cheese",
+            "Podhalanski", "Poivre d'Ane", "Polkolbin", "Pont l'Eveque",
+            "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean",
+            "Processed Cheddar", "Provolone", "Provolone (Australian)",
+            "Pyengana Cheddar", "Pyramide", "Quark", "Quark (Australian)",
+            "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango",
+            "Queso de Murcia", "Queso del Montsec", "Queso del Tietar",
+            "Queso Fresco", "Queso Fresco (Adobera)", "Queso Iberico",
+            "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette",
+            "Ragusano", "Raschera", "Reblochon", "Red Leicester",
+            "Regal de la Dombes", "Reggianito", "Remedou", "Requeson",
+            "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata",
+            "Ridder", "Rigotte", "Rocamadour", "Rollot", "Romano",
+            "Romans Part Dieu", "Roncal", "Roquefort", "Roule",
+            "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu",
+            "Saaland Pfarr", "Saanenkaese", "Saga", "Sage Derby",
+            "Sainte Maure", "Saint-Marcellin", "Saint-Nectaire",
+            "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza",
+            "Schabzieger", "Schloss", "Selles sur Cher", "Selva", "Serat",
+            "Seriously Strong Cheddar", "Serra da Estrela", "Sharpam",
+            "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene",
+            "Smoked Gouda", "Somerset Brie", "Sonoma Jack",
+            "Sottocenare al Tartufo", "Soumaintrain", "Sourire Lozerien",
+            "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote",
+            "Sveciaost", "Swaledale", "Sweet Style Swiss", "Swiss",
+            "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea",
+            "Testouri", "Tete de Moine", "Tetilla", "Texas Goat Cheese",
+            "Tibet", "Tillamook Cheddar", "Tilsit", "Timboon Brie", "Toma",
+            "Tomme Brulee", "Tomme d'Abondance", "Tomme de Chevre",
+            "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans",
+            "Tommes", "Torta del Casar", "Toscanello", "Touree de L'Aubier",
+            "Tourmalet", "Trappe (Veritable)", "Trois Cornes De Vendee",
+            "Tronchon", "Trou du Cru", "Truffe", "Tupi", "Turunmaa",
+            "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco",
+            "Vendomois", "Vieux Corse", "Vignotte", "Vulscombe",
+            "Waimata Farmhouse Blue", "Washed Rind Cheese (Australian)",
+            "Waterloo", "Weichkaese", "Wellington", "Wensleydale",
+            "White Stilton", "Whitestone Farmhouse", "Wigmore",
+            "Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
+            "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
+            "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar1.java
new file mode 100644
index 0000000..d9bf360
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar1.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+
+/**
+ * Demonstrates how to use progress bars as widgets and in the title bar.  The progress bar
+ * in the title will be shown until the progress is complete, at which point it fades away.
+ */
+public class ProgressBar1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Request the progress bar to be shown in the title
+        requestWindowFeature(Window.FEATURE_PROGRESS);
+        setContentView(R.layout.progressbar_1);
+        setProgressBarVisibility(true);
+        
+        final ProgressBar progressHorizontal = (ProgressBar) findViewById(R.id.progress_horizontal);
+        setProgress(progressHorizontal.getProgress() * 100);
+        setSecondaryProgress(progressHorizontal.getSecondaryProgress() * 100);
+        
+        Button button = (Button) findViewById(R.id.increase);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                progressHorizontal.incrementProgressBy(1);
+                // Title progress is in range 0..10000
+                setProgress(100 * progressHorizontal.getProgress());
+            }
+        });
+
+        button = (Button) findViewById(R.id.decrease);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                progressHorizontal.incrementProgressBy(-1);
+                // Title progress is in range 0..10000
+                setProgress(100 * progressHorizontal.getProgress());
+            }
+        });
+
+        button = (Button) findViewById(R.id.increase_secondary);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                progressHorizontal.incrementSecondaryProgressBy(1);
+                // Title progress is in range 0..10000
+                setSecondaryProgress(100 * progressHorizontal.getSecondaryProgress());
+            }
+        });
+
+        button = (Button) findViewById(R.id.decrease_secondary);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                progressHorizontal.incrementSecondaryProgressBy(-1);
+                // Title progress is in range 0..10000
+                setSecondaryProgress(100 * progressHorizontal.getSecondaryProgress());
+            }
+        });
+        
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.java b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.java
new file mode 100644
index 0000000..1c41b78
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Window;
+
+
+/**
+ * Demonstrates the use of indeterminate progress bars as widgets and in the
+ * window's title bar. The widgets show the 3 different sizes of circular
+ * progress bars that can be used.
+ */
+public class ProgressBar2 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Request for the progress bar to be shown in the title
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        
+        setContentView(R.layout.progressbar_2);
+        
+        // Make sure the progress bar is visible
+        setProgressBarVisibility(true);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar3.java b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar3.java
new file mode 100644
index 0000000..285f07b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar3.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Demonstrates the use of progress dialogs.  Uses {@link Activity#onCreateDialog}
+ * and {@link Activity#showDialog} to ensure the dialogs will be properly saved
+ * and restored.
+ */
+public class ProgressBar3 extends Activity {
+
+    ProgressDialog mDialog1;
+    ProgressDialog mDialog2;
+
+    private static final int DIALOG1_KEY = 0;
+    private static final int DIALOG2_KEY = 1;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.progressbar_3);
+
+        Button button = (Button) findViewById(R.id.showIndeterminate);
+        button.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG1_KEY);
+            }
+        });
+
+        button = (Button) findViewById(R.id.showIndeterminateNoTitle);
+        button.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                showDialog(DIALOG2_KEY);
+            }
+        });
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case DIALOG1_KEY: {
+                ProgressDialog dialog = new ProgressDialog(this);
+                dialog.setTitle("Indeterminate");
+                dialog.setMessage("Please wait while loading...");
+                dialog.setIndeterminate(true);
+                dialog.setCancelable(true);
+                return dialog;
+            }
+            case DIALOG2_KEY: {
+                ProgressDialog dialog = new ProgressDialog(this);
+                dialog.setMessage("Please wait while loading...");
+                dialog.setIndeterminate(true);
+                dialog.setCancelable(true);
+                return dialog;
+            }
+        }
+        return null;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java
new file mode 100644
index 0000000..ee396b3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Window;
+import android.view.View;
+import android.widget.Button;
+
+
+/**
+ * Demonstrates how to use an indetermiate progress indicator in the window's title bar.
+ */
+public class ProgressBar4 extends Activity {
+    private boolean mToggleIndeterminate = false;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Request progress bar
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.progressbar_4);
+        setProgressBarIndeterminateVisibility(mToggleIndeterminate);
+        
+        Button button = (Button) findViewById(R.id.toggle);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                mToggleIndeterminate = !mToggleIndeterminate;
+                setProgressBarIndeterminateVisibility(mToggleIndeterminate);
+            }
+        });
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RadioGroup1.java b/samples/ApiDemos/src/com/example/android/apis/view/RadioGroup1.java
new file mode 100644
index 0000000..4d91192
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RadioGroup1.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.RadioGroup;
+import android.widget.Button;
+import android.widget.RadioButton;
+import android.widget.LinearLayout;
+
+
+public class RadioGroup1 extends Activity implements RadioGroup.OnCheckedChangeListener,
+        View.OnClickListener {
+
+    private TextView mChoice;
+    private RadioGroup mRadioGroup;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.radio_group_1);
+        mRadioGroup = (RadioGroup) findViewById(R.id.menu);
+
+        // test adding a radio button programmatically
+        RadioButton newRadioButton = new RadioButton(this);
+        newRadioButton.setText(R.string.radio_group_snack);
+        newRadioButton.setId(R.id.snack);
+        LinearLayout.LayoutParams layoutParams = new RadioGroup.LayoutParams(
+                RadioGroup.LayoutParams.WRAP_CONTENT,
+                RadioGroup.LayoutParams.WRAP_CONTENT);
+        mRadioGroup.addView(newRadioButton, 0, layoutParams);
+
+        // test listening to checked change events
+        String selection = getString(R.string.radio_group_selection);
+        mRadioGroup.setOnCheckedChangeListener(this);
+        mChoice = (TextView) findViewById(R.id.choice);
+        mChoice.setText(selection + mRadioGroup.getCheckedRadioButtonId());
+
+        // test clearing the selection
+        Button clearButton = (Button) findViewById(R.id.clear);
+        clearButton.setOnClickListener(this);
+    }
+
+    public void onCheckedChanged(RadioGroup group, int checkedId) {
+        String selection = getString(R.string.radio_group_selection);
+        String none = getString(R.string.radio_group_none);
+        mChoice.setText(selection +
+                (checkedId == View.NO_ID ? none : checkedId));
+    }
+
+    public void onClick(View v) {
+        mRadioGroup.clearCheck();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
new file mode 100644
index 0000000..97416d4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.RatingBar;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.example.android.apis.R;
+
+/**
+ * Demonstrates how to use a rating bar
+ */
+public class RatingBar1 extends Activity implements RatingBar.OnRatingBarChangeListener {
+    RatingBar mSmallRatingBar;
+    RatingBar mIndicatorRatingBar;
+    TextView mRatingText;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.ratingbar_1);
+        
+        mRatingText = (TextView) findViewById(R.id.rating);
+
+        // We copy the most recently changed rating on to these indicator-only
+        // rating bars
+        mIndicatorRatingBar = (RatingBar) findViewById(R.id.indicator_ratingbar);
+        mSmallRatingBar = (RatingBar) findViewById(R.id.small_ratingbar);
+        
+        // The different rating bars in the layout. Assign the listener to us.
+        ((RatingBar)findViewById(R.id.ratingbar1)).setOnRatingBarChangeListener(this);
+        ((RatingBar)findViewById(R.id.ratingbar2)).setOnRatingBarChangeListener(this);
+    }
+
+    public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromTouch) {
+        final int numStars = ratingBar.getNumStars();
+        mRatingText.setText( 
+                getString(R.string.ratingbar_rating) + " " + rating + "/" + numStars);
+
+        // Since this rating bar is updated to reflect any of the other rating
+        // bars, we should update it to the current values.
+        if (mIndicatorRatingBar.getNumStars() != numStars) {
+            mIndicatorRatingBar.setNumStars(numStars);
+            mSmallRatingBar.setNumStars(numStars);
+        }
+        if (mIndicatorRatingBar.getRating() != rating) {
+            mIndicatorRatingBar.setRating(rating);
+            mSmallRatingBar.setRating(rating);
+        }
+        final float ratingBarStepSize = ratingBar.getStepSize();
+        if (mIndicatorRatingBar.getStepSize() != ratingBarStepSize) {
+            mIndicatorRatingBar.setStepSize(ratingBarStepSize);
+            mSmallRatingBar.setStepSize(ratingBarStepSize);
+        }
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout1.java b/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout1.java
new file mode 100644
index 0000000..1c9f824
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout1.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * A simple layout which demonstrates stretching a view to fill the space between two other views.
+ */
+public class RelativeLayout1 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.relative_layout_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout2.java b/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout2.java
new file mode 100644
index 0000000..635d9f3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout2.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Builds building a simple form using a RelativeLayout
+ * 
+ */
+public class RelativeLayout2 extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.relative_layout_2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar1.java
new file mode 100644
index 0000000..0b3c19a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class ScrollBar1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.scrollbar1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar2.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar2.java
new file mode 100644
index 0000000..09a8bb0
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar2.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class ScrollBar2 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.scrollbar2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar3.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar3.java
new file mode 100644
index 0000000..74c5876
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar3.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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.os.Bundle;
+import android.view.View;
+
+import com.example.android.apis.R;
+
+
+public class ScrollBar3 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.scrollbar3);
+        
+        findViewById(R.id.view3).setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollView1.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView1.java
new file mode 100644
index 0000000..b3a903a
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView1.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * Demonstrates wrapping a layout in a ScrollView.
+ *
+ */
+public class ScrollView1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.scroll_view_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
new file mode 100644
index 0000000..89e4003
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Button;
+
+
+/**
+ * Demonstrates wrapping a layout in a ScrollView.
+ *
+ */
+public class ScrollView2 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.scroll_view_2);
+
+        LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
+        for (int i = 2; i < 64; i++) {
+            TextView textView = new TextView(this);
+            textView.setText("Text View " + i);
+            LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
+                    LinearLayout.LayoutParams.FILL_PARENT,
+                    LinearLayout.LayoutParams.WRAP_CONTENT
+            );
+            layout.addView(textView, p);
+
+            Button buttonView = new Button(this);
+            buttonView.setText("Button " + i);
+            layout.addView(buttonView, p);
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java
new file mode 100644
index 0000000..15bb013
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Demonstrates how to use a seek bar
+ */
+public class SeekBar1 extends Activity implements SeekBar.OnSeekBarChangeListener {
+    
+    SeekBar mSeekBar;
+    TextView mProgressText;
+    TextView mTrackingText;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.seekbar_1);
+        
+        mSeekBar = (SeekBar)findViewById(R.id.seek);
+        mSeekBar.setOnSeekBarChangeListener(this);
+        mProgressText = (TextView)findViewById(R.id.progress);
+        mTrackingText = (TextView)findViewById(R.id.tracking);
+    }
+
+    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
+        mProgressText.setText(progress + " " + 
+                getString(R.string.seekbar_from_touch) + "=" + fromTouch);
+    }
+
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        mTrackingText.setText(getString(R.string.seekbar_tracking_on));
+    }
+
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        mTrackingText.setText(getString(R.string.seekbar_tracking_off));
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Spinner1.java b/samples/ApiDemos/src/com/example/android/apis/view/Spinner1.java
new file mode 100644
index 0000000..a35a909
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Spinner1.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+
+public class Spinner1 extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.spinner_1);
+
+        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
+        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
+                this, R.array.colors, android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s1.setAdapter(adapter);
+
+        Spinner s2 = (Spinner) findViewById(R.id.spinner2);
+        adapter = ArrayAdapter.createFromResource(this, R.array.planets,
+                android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s2.setAdapter(adapter);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout1.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout1.java
new file mode 100644
index 0000000..98f6b31
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class TableLayout1 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
new file mode 100644
index 0000000..f1f8f24
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.TableLayout;
+import android.widget.Button;
+import android.os.Bundle;
+import android.view.View;
+
+
+public class TableLayout10 extends Activity {
+    private boolean mShrink;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_10);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
new file mode 100644
index 0000000..770238f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * <p>This example shows how to use horizontal gravity in a table layout.</p>
+ */
+public class TableLayout11 extends Activity {
+    private boolean mShrink;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_11);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
new file mode 100644
index 0000000..14cbd0d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * <p>This example shows how to use cell spanning in a table layout.</p>
+ */
+public class TableLayout12 extends Activity {
+    private boolean mShrink;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_12);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout2.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout2.java
new file mode 100644
index 0000000..3e60563
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout2.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class TableLayout2 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_2);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout3.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout3.java
new file mode 100644
index 0000000..82a545c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout3.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class TableLayout3 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_3);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout4.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout4.java
new file mode 100644
index 0000000..53a1055
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout4.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class TableLayout4 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_4);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout5.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout5.java
new file mode 100644
index 0000000..9422218
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout5.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class TableLayout5 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_5);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout6.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout6.java
new file mode 100644
index 0000000..b6a9125
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout6.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class TableLayout6 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_6);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout7.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout7.java
new file mode 100644
index 0000000..22fc4a5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout7.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+
+
+public class TableLayout7 extends Activity {
+    private boolean mShortcutsCollapsed;
+    private boolean mCheckmarksCollapsed;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_7);
+
+        final TableLayout table = (TableLayout) findViewById(R.id.menu);
+        Button button = (Button) findViewById(R.id.toggle1);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                mShortcutsCollapsed = !mShortcutsCollapsed;
+                table.setColumnCollapsed(2, mShortcutsCollapsed);
+            }
+        });
+        button = (Button) findViewById(R.id.toggle2);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                mCheckmarksCollapsed = !mCheckmarksCollapsed;
+                table.setColumnCollapsed(0, mCheckmarksCollapsed);
+            }
+        });
+
+        mCheckmarksCollapsed = table.isColumnCollapsed(0);
+        mShortcutsCollapsed = table.isColumnCollapsed(2);
+
+        appendRow(table);
+    }
+
+    private void appendRow(TableLayout table) {
+        TableRow row = new TableRow(this);
+
+        TextView label = new TextView(this);
+        label.setText(R.string.table_layout_7_quit);
+        label.setPadding(3, 3, 3, 3);
+
+        TextView shortcut = new TextView(this);
+        shortcut.setText(R.string.table_layout_7_ctrlq);
+        shortcut.setPadding(3, 3, 3, 3);
+        shortcut.setGravity(Gravity.RIGHT | Gravity.TOP);
+
+        row.addView(label, new TableRow.LayoutParams(1));
+        row.addView(shortcut, new TableRow.LayoutParams());
+
+        table.addView(row, new TableLayout.LayoutParams());
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout8.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout8.java
new file mode 100644
index 0000000..99ca4ac
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout8.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.TableLayout;
+import android.widget.Button;
+import android.widget.TableRow;
+import android.widget.TextView;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+
+
+public class TableLayout8 extends Activity {
+    private boolean mStretch;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_8);
+
+        final TableLayout table = (TableLayout) findViewById(R.id.menu);
+        Button button = (Button) findViewById(R.id.toggle);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                mStretch = !mStretch;
+                table.setColumnStretchable(1, mStretch);
+            }
+        });
+
+        mStretch = table.isColumnStretchable(1);
+
+        appendRow(table);
+    }
+
+    private void appendRow(TableLayout table) {
+        TableRow row = new TableRow(this);
+
+        TextView label = new TextView(this);
+        label.setText(R.string.table_layout_8_quit);
+        label.setPadding(3, 3, 3, 3);
+
+        TextView shortcut = new TextView(this);
+        shortcut.setText(R.string.table_layout_8_ctrlq);
+        shortcut.setPadding(3, 3, 3, 3);
+        shortcut.setGravity(Gravity.RIGHT | Gravity.TOP);
+
+        row.addView(label, new TableRow.LayoutParams(1));
+        row.addView(shortcut, new TableRow.LayoutParams());
+
+        table.addView(row, new TableLayout.LayoutParams());
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout9.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout9.java
new file mode 100644
index 0000000..f99111d
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout9.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.widget.TableLayout;
+import android.widget.Button;
+import android.os.Bundle;
+import android.view.View;
+
+
+public class TableLayout9 extends Activity {
+    private boolean mShrink;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.table_layout_9);
+
+        final TableLayout table = (TableLayout) findViewById(R.id.menu);
+        Button button = (Button) findViewById(R.id.toggle);
+        button.setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                mShrink = !mShrink;
+                table.setColumnShrinkable(0, mShrink);
+            }
+        });
+
+        mShrink = table.isColumnShrinkable(0);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
new file mode 100644
index 0000000..455969e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 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.TabActivity;
+import android.os.Bundle;
+import android.widget.TabHost;
+import android.widget.TabHost.TabSpec;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.example.android.apis.R;
+
+/**
+ * An example of tabs that uses labels ({@link TabSpec#setIndicator(CharSequence)})
+ * for its indicators and views by id from a layout file ({@link TabSpec#setContent(int)}).
+ */
+public class Tabs1 extends TabActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        TabHost tabHost = getTabHost();
+        
+        LayoutInflater.from(this).inflate(R.layout.tabs1, tabHost.getTabContentView(), true);
+
+        tabHost.addTab(tabHost.newTabSpec("tab1")
+                .setIndicator("tab1")
+                .setContent(R.id.view1));
+        tabHost.addTab(tabHost.newTabSpec("tab3")
+                .setIndicator("tab2")
+                .setContent(R.id.view2));
+        tabHost.addTab(tabHost.newTabSpec("tab3")
+                .setIndicator("tab3")
+                .setContent(R.id.view3));
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java
new file mode 100644
index 0000000..795a86b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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.TabActivity;
+import android.os.Bundle;
+import android.widget.TabHost;
+import android.widget.TextView;
+import android.view.View;
+import com.example.android.apis.R;
+
+/**
+ * Example of using a tab content factory for the content via {@link TabHost.TabSpec#setContent(android.widget.TabHost.TabContentFactory)}
+ *
+ * It also demonstrates using an icon on one of the tabs via {@link TabHost.TabSpec#setIndicator(CharSequence, android.graphics.drawable.Drawable)}
+ *
+ */
+public class Tabs2 extends TabActivity implements TabHost.TabContentFactory {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final TabHost tabHost = getTabHost();
+        tabHost.addTab(tabHost.newTabSpec("tab1")
+                .setIndicator("tab1", getResources().getDrawable(R.drawable.star_big_on))
+                .setContent(this));
+        tabHost.addTab(tabHost.newTabSpec("tab2")
+                .setIndicator("tab2")
+                .setContent(this));
+        tabHost.addTab(tabHost.newTabSpec("tab3")
+                .setIndicator("tab3")
+                .setContent(this));
+    }
+
+    /** {@inheritDoc} */
+    public View createTabContent(String tag) {
+        final TextView tv = new TextView(this);
+        tv.setText("Content for tab with tag " + tag);
+        return tv;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java
new file mode 100644
index 0000000..e09f041
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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.TabActivity;
+import android.os.Bundle;
+import android.widget.TabHost;
+import android.content.Intent;
+
+/**
+ * An example of tab content that launches an activity via {@link android.widget.TabHost.TabSpec#setContent(android.content.Intent)}
+ */
+public class Tabs3 extends TabActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final TabHost tabHost = getTabHost();
+
+        tabHost.addTab(tabHost.newTabSpec("tab1")
+                .setIndicator("list")
+                .setContent(new Intent(this, List1.class)));
+
+        tabHost.addTab(tabHost.newTabSpec("tab2")
+                .setIndicator("photo list")
+                .setContent(new Intent(this, List8.class)));
+        
+        // This tab sets the intent flag so that it is recreated each time
+        // the tab is clicked.
+        tabHost.addTab(tabHost.newTabSpec("tab3")
+                .setIndicator("destroy")
+                .setContent(new Intent(this, Controls2.class)
+                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.java b/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.java
new file mode 100644
index 0000000..b964512
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.TextSwitcher;
+import android.widget.TextView;
+import android.widget.ViewSwitcher;
+
+/**
+ * Uses a TextSwitcher.
+ */
+public class TextSwitcher1 extends Activity implements ViewSwitcher.ViewFactory,
+        View.OnClickListener {
+
+    private TextSwitcher mSwitcher;
+
+    private int mCounter = 0;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.text_switcher_1);
+
+        mSwitcher = (TextSwitcher) findViewById(R.id.switcher);
+        mSwitcher.setFactory(this);
+
+        Animation in = AnimationUtils.loadAnimation(this,
+                android.R.anim.fade_in);
+        Animation out = AnimationUtils.loadAnimation(this,
+                android.R.anim.fade_out);
+        mSwitcher.setInAnimation(in);
+        mSwitcher.setOutAnimation(out);
+
+        Button nextButton = (Button) findViewById(R.id.next);
+        nextButton.setOnClickListener(this);
+
+        updateCounter();
+    }
+
+    public void onClick(View v) {
+        mCounter++;
+        updateCounter();
+    }
+
+    private void updateCounter() {
+        mSwitcher.setText(String.valueOf(mCounter));
+    }
+
+    public View makeView() {
+        TextView t = new TextView(this);
+        t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
+        t.setTextSize(36);
+        return t;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Visibility1.java b/samples/ApiDemos/src/com/example/android/apis/view/Visibility1.java
new file mode 100644
index 0000000..243eba7
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Visibility1.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+
+/**
+ * Demonstrates making a view VISIBLE, INVISIBLE and GONE
+ *
+ */
+public class Visibility1 extends Activity {
+
+    private View mVictim;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.visibility_1);
+
+        // Find the view whose visibility will change
+        mVictim = findViewById(R.id.victim);
+
+        // Find our buttons
+        Button visibleButton = (Button) findViewById(R.id.vis);
+        Button invisibleButton = (Button) findViewById(R.id.invis);
+        Button goneButton = (Button) findViewById(R.id.gone);
+
+        // Wire each button to a click listener
+        visibleButton.setOnClickListener(mVisibleListener);
+        invisibleButton.setOnClickListener(mInvisibleListener);
+        goneButton.setOnClickListener(mGoneListener);
+    }
+
+    OnClickListener mVisibleListener = new OnClickListener() {
+        public void onClick(View v) {
+            mVictim.setVisibility(View.VISIBLE);
+        }
+    };
+
+    OnClickListener mInvisibleListener = new OnClickListener() {
+        public void onClick(View v) {
+            mVictim.setVisibility(View.INVISIBLE);
+        }
+    };
+
+    OnClickListener mGoneListener = new OnClickListener() {
+        public void onClick(View v) {
+            mVictim.setVisibility(View.GONE);
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/WebView1.java b/samples/ApiDemos/src/com/example/android/apis/view/WebView1.java
new file mode 100644
index 0000000..1cef034
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/WebView1.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.webkit.WebView;
+
+import com.example.android.apis.R;
+
+
+/**
+ * Sample creating 10 webviews.
+ */
+public class WebView1 extends Activity {
+    
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        setContentView(R.layout.webview_1);
+        
+        final String mimeType = "text/html";
+        final String encoding = "utf-8";
+        
+        WebView wv;
+        
+        wv = (WebView) findViewById(R.id.wv1);
+        wv.loadData("<a href='x'>Hello World! - 1</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv2);
+        wv.loadData("<a href='x'>Hello World! - 2</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv3);
+        wv.loadData("<a href='x'>Hello World! - 3</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv4);
+        wv.loadData("<a href='x'>Hello World! - 4</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv5);
+        wv.loadData("<a href='x'>Hello World! - 5</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv6);
+        wv.loadData("<a href='x'>Hello World! - 6</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv7);
+        wv.loadData("<a href='x'>Hello World! - 7</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv8);
+        wv.loadData("<a href='x'>Hello World! - 8</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv9);
+        wv.loadData("<a href='x'>Hello World! - 9</a>", mimeType, encoding);
+        
+        wv = (WebView) findViewById(R.id.wv10);
+        wv.loadData("<a href='x'>Hello World! - 10</a>", mimeType, encoding);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/_index.html b/samples/ApiDemos/src/com/example/android/apis/view/_index.html
new file mode 100644
index 0000000..9497f8e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/_index.html
@@ -0,0 +1,298 @@
+<h3>RelativeLayout</h3>
+<dl>
+  <dt><a href="RelativeLayout1.html">1. Vertical</a></dt>
+  <dd>Demonstrates a simple relative layout.</dd>
+
+  <dt><a href="RelativeLayout2.html">2. Simple Form</a></dt>
+  <dd>Demonstrates a more complex relative layout to create a form. </dd>
+</dl>
+
+<h3>LinearLayout</h3>
+<dl>
+  <dt><a href="LinearLayout1.html">1. Vertical</a></dt>
+  <dd>Demonstrates a simple LinearLayout, with child width set to WRAP_CONTENT. </dd>
+
+  <dt><a href="LinearLayout2.html">2. Vertical (Fill Screen)</a></dt>
+  <dd>Demonstrates a simple LinearLayout, with child width set to FILL_PARENT.</dd>
+
+  <dt><a href="LinearLayout3.html">3. Vertical (Padded)</a></dt>
+  <dd>Demonstrates a LinearLayout where one of the elements can expand to fill any remaining screen space (weight=1). </dd>
+
+  <dt><a href="LinearLayout4.html">4. Horizontal</a></dt>
+  <dd>Demonstrates a horizontal LinearLayout, plus an expanding column. </dd>
+
+  <dt><a href="LinearLayout5.html">5. Simple Form</a></dt>
+  <dd>Demonstrates nested layouts to create a user form.</dd>
+
+  <dt><a href="LinearLayout6.html">6. Uniform Size</a></dt>
+  <dd>LinearLayout which uses a combination of wrap_content on itself and fill_parent on its children to get every item to be the same width.</dd>
+
+  <dt><a href="LinearLayout7.html">7. Fill Parent</a></dt>
+  <dd>Demonstrates a horizontal linear layout with equally sized columns. Some columns force their height to match the parent.</dd>
+
+  <dt><a href="LinearLayout8.html">8. Gravity</a></dt>
+  <dd>Demonstrates a simple linear layout with menu options demonstrating horizontal and vertical gravity options.</dd>
+
+  <dt><a href="LinearLayout9.html">9. Layout Weight</a></dt>
+  <dd> Demonstrates how the layout_weight attribute can shrink an element too big to fit on screen.</dd>
+
+</dl>
+
+<h3>ScrollView</h3>
+<dl>
+  <dt><a href="ScrollView1.html">1. Short</a></dt>
+  <dd>Demonstrates scrolling screen with buttons altermating with a text view. </dd>
+
+  <dt><a href="ScrollView2.html">2. Long</a></dt>
+  <dd>Demonstrates a longer scrolling screen similar to ScrollView1. </dd>
+</dl>
+
+<h3>TableLayout</h3>
+<dl>
+  <dt><a href="TableLayout1.html">1. Basic</a></dt>
+  <dd>Demonstrates a basic TableLayout with identical children. </dd>
+  
+  <dt><a href="TableLayout2.html">2. Empty Cells</a></dt>
+  <dd>Demonstrates a TableLayout with column-spanning rows and different child objects. </dd>
+  
+  <dt><a href="TableLayout3.html">3. Long Content</a></dt>
+  <dd>Rows have different number of columns and content doesn't fit on screen: column 4 of row 2 shrinks all of the other columns </dd>
+  
+  <dt><a href="TableLayout4.html">4. Stretchable</a></dt>
+  <dd>Demonstrates a TableLayout with a stretchable column. </dd>
+
+  <dt><a href="TableLayout5.html">5. Spanning and Stretchable</a></dt>
+  <dd>Demonstrates a complex TableLayout with spanning columns and stretchable columns to create a menu-like layout. </dd>
+
+  <dt><a href="TableLayout6.html">6. More Spanning and Stretchable</a></dt>
+  <dd>Similar to example 5, but with an additional &quot;checked&quot; column. </dd>
+
+  <dt><a href="TableLayout7.html">7. Column Collapse</a></dt>
+  <dd>Similar to example 6, but now with buttons on the bottom of the screen that enable you dynamically hide or show columns. </dd>
+
+  <dt><a href="TableLayout8.html">8. Toggle Stretch</a></dt>
+  <dd>Demonstrates toggling the &quot;stretch&quot; value on a column to fill the screen width. </dd>
+
+  <dt><a href="TableLayout9.html">9. Toggle Shrink</a></dt>
+  <dd>Demonstrates toggling the &quot;shrink&quot; value on a column to make an over-wide table shrink to fit the screen size. </dd>
+
+  <dt><a href="TableLayout10.html">10. Simple Form</a></dt>
+  <dd>Demonstrates using a table to design a user form. </dd>
+
+  <dt><a href="TableLayout11.html">11. Gravity</a></dt>
+  <dd>Demonstrates the use of advanced gravity attributes, such as <em>center_horizontal</em> and <em>right|bottom</em>                to align cell contents in a table. </dd>
+
+  <dt><a href="TableLayout12.html">12. Various Widths</a></dt>
+  <dd>Demonstrates the use of elements of various widths in a table. </dd>
+</dl>
+
+<h3>Baseline</h3>
+<p>Demonstrates the use of the <em>android:layout_alignBaseline</em> XML attribute in various page layouts.</p>
+<dl>
+  <dt><a href="Baseline1.html">1. Top</a></dt>
+  <dd>Demonstrates the default baseline alignment in a simple LinearLayout with items at the top of the screen. </dd>
+
+  <dt><a href="Baseline2.html">2. Bottom</a></dt>
+  <dd>Demonstrates the default baseline alignment in a simple LinearLayout with items at the bottom of the screen.</dd>
+
+  <dt><a href="Baseline3.html">3. Center</a></dt>
+  <dd>Demonstrates the default baseline alignment in a simple LinearLayout with items in the center of the screen.</dd>
+
+  <dt><a href="Baseline4.html">4. Everywhere</a></dt>
+  <dd>Demonstrates the default baseline alignment in a complex LinearLayout.</dd>
+  
+  <dt><a href="Baseline5.html">5. Everywhere</a></dt>
+  <dd>Demonstrates turning off baseline alignment in a LinearLayout. </dd>
+
+  <dt><a href="Baseline6.html">6. Multi-line</a></dt>
+  <dd>Demonstrates a baseline alignment with a multiline field. </dd>
+
+  <dt><a href="Baseline7.html">7. Relative</a></dt>
+  <dd>Demonstrates baseline alignment in a RelativeLayout. </dd>
+
+  <dt><a href="BaselineNested1.html">BaselineNested1</a></dt>
+  <dd>Demonstrates baseline aligning specific elements in three parallel vertical LinearLayout objects.</dd>
+
+  <dt><a href="BaselineNested2.html">BaselineNested2</a></dt>
+  <dd>Demonstrates baseline aligning specific elements in three mixed vertical and horizontal LinearLayout objects.</dd>
+  
+  <dt><a href="BaselineNested3.html">BaselineNested3</a></dt>
+  <dd>Demonstrates baseline alignment within nested LinearLayout objects. </dd>
+</dl>
+
+<h3>Radio Group</h3>
+<dl>
+  <dt><a href="RadioGroup1.html">Radio Group</a></dt>
+  <dd>Demonstrates using radio buttons and capturing the selected item. </dd>
+</dl>
+
+<h3>ScrollBars</h3>
+<dl>
+  <dt><a href="ScrollBar1.html">1. Basic</a></dt>
+  <dd>Demonstrates a scrollable LinearLayout object. </dd>
+
+  <dt><a href="ScrollBar2.html">2. Fancy</a></dt>
+  <dd>Demonstrates a scrollable LinearLayout object with a custom thumb slider image. </dd>
+</dl>
+
+<h3>Visibility</h3>
+<dl>
+  <dt><a href="Visibility1.html">Visibility</a></dt>
+  <dd>Demonstrates toggling the visibility of a View object between visible, invisible, and gone. </dd>
+</dl>
+
+<h3>Lists</h3>
+<dl>
+  <dt><a href="List1.html">1. Array</a></dt>
+  <dd> Demonstrates binding a ListAdapter to a string array as a data source, and displaying the elements on the screen. </dd>
+  
+  <dt><a href="List2.html">2. Cursor (People)</a></dt>
+  <dd> Demonstrates binding results from a database query to a field in a template. </dd>
+  
+  <dt><a href="List3.html">3. Cursor (Phones)</a></dt>
+  <dd> Demonstrates binding multiple columns from a database query to fields in a template. </dd>
+  
+  <dt><a href="List4.html">4. ListAdapter</a></dt>
+  <dd> Demonstrates implementing a custom ListAdapter to return View objects laid out in a custom manner. </dd>
+  
+  <dt><a href="List5.html">5. Separators</a></dt>
+  <dd> Demonstrates implementing a custom ListAdapter that includes separators between some items. </dd>
+  
+  <dt><a href="List6.html">6. ListAdapter Collapsed</a></dt>
+  <dd>Demonstrates another custom list adapter with that returns expandible items. </dd>
+  
+  <dt><a href="List7.html">7. Cursor (Phones)</a></dt>
+  <dd> Demonstrates a list adapter where data comes from a Cursor object. </dd>
+  
+  <dt><a href="List8.html">8. Photos</a></dt>
+  <dd> Demonstrates a list activity that uses a custom ListAdapter, setting the view for an empty item, and also how to customize the layout of a ListActivity. </dd>
+</dl>
+
+
+
+<h3>Custom</h3>
+<dl>
+  <dt><a href="CustomView1.html">CustomView</a></dt>
+  <dd>Demonstrates implementing a custom view subclass. </dd>
+</dl>
+
+<h3>ImageButton</h3>
+<dl>
+  <dt><a href="ImageButton1.html">ImageButton</a></dt>
+  <dd>Demonstrates an ImageButton: a button with an arbitrary graphic on it. </dd>
+</dl>
+
+<h3>Date Widgets</h3>
+<dl>
+  <dt><a href="DateWidgets1.html">1. Dialog</a></dt>
+  <dd>Demonstrates the DatePickerDialog and TimePickerDialog picker dialogs.</dd>
+
+  <dt><a href="DateWidgets2.html">2. Inline</a></dt>
+  <dd>Demonstrates using a TimePicker directly in a layout without using a confirmation button or dialog.</dd>
+</dl>
+
+<h3>Gallery</h3>
+<dl>
+  <dt><a href="Gallery1.html">1. Icons</a></dt>
+  <dd> Demonstrates implementing a Gallery widget and extending GalleryAdapter to create a custom class to serve out source images to the widget. </dd>
+  
+  <dt><a href="Gallery2.html">2. People</a></dt>
+  <dd>Demonstrates populating a Gallery with images from the contacts photos. </dd>
+</dl>
+
+<h3>Spinner</h3>
+<dl>
+  <dt><a href="Spinner1.html">Spinner</a></dt>
+  <dd> Demonstrates populating two Spinner widgets with values. </dd>
+</dl>
+
+<h3>Grid</h3>
+<dl>
+  <dt><a href="Grid1.html">1. Icon Grid</a></dt>
+  <dd> Demonstrates populating a GridView widget with a list of applications using a custom ListAdapter object.</dd>
+
+  <dt><a href="Grid2.html">2. Photo Grid</a></dt>
+  <dd> Demonstrates populating a GridView widget with images using a custom ListAdapter object. </dd>
+</dl>
+
+<h3>Ticker</h3>
+<dl>
+  <dt><a href="Ticker1.html">Ticker</a></dt>
+  <dd> Demonstrates a Ticker widget, which scrolls text across the screen.</dd>
+</dl>
+
+<h3>ImageSwitcher</h3>
+<dl>
+  <dt><a href="ImageSwitcher1.html">ImageSwitcher</a></dt>
+  <dd>Demonstrates using the ImageSwitcher widget with a custom Adapter.</dd>
+</dl>
+
+<h3>TextSwitcher</h3>
+<dl>
+  <dt><a href="TextSwitcher1.html">TextSwitcher</a></dt>
+  <dd>Demonstrates using the TextSwitcher widget. </dd>
+</dl>
+
+<h3>Animation</h3>
+<dl>
+  <dt><a href="Animation1.html">1. Shake</a></dt>
+  <dd>Demonstrates a simple tweened animation (android.view.animation.Animation). </dd>
+
+  <dt><a href="Animation2.html">2. Push</a></dt>
+  <dd>Demonstrates a variety of transformations (android.view.animation.Animation), including fading, motion, and rotation. </dd>
+</dl>
+
+<h3>Controls</h3>
+<dl>
+  <dt><a href="Controls1.html">1. Theme White</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the white theme. </dd>
+</dl>
+<dl>
+  <dt><a href="Controls2.html">2. Theme Dark</a></dt>
+  <dd>Demonstrates a variety of common form type widgets, such as check boxes and radio buttons using the dark theme. </dd>
+</dl>
+
+<h3>Auto Complete</h3>
+<dl>
+  <dt><a href="AutoComplete1.html">1. Screen Top</a></dt>
+  <dd>Demonstrates the use of AutoCompleteTextView, an autocomplete dropdown box below a text box, with data taken from an array. </dd>
+
+  <dt><a href="AutoComplete2.html">2. Screen Bottom</a></dt>
+  <dd>Demonstrates an autocomplete box above a text box.</dd>
+
+  <dt><a href="AutoComplete3.html">3. Scroll</a></dt>
+  <dd>Demonstrates an autocomplete text box in the midst of a vertical list. </dd>
+
+  <dt><a href="AutoComplete4.html">4. Contacts</a></dt>
+  <dd>Demonstrates an autocomplete text box that gets its content from a database query. </dd>
+  
+  <dt><a href="AutoComplete5.html">5. Contacts with Hint</a></dt>
+  <dd>Demonstates an autocomplete text box that understands the * wildcard. </dd>
+</dl>
+
+<h3>Progress Bar</h3>
+<dl>
+  <dt><a href="ProgressBar1.html">1. Incremental</a></dt>
+  <dd>Demonstrates large and small rotating progress indicators that can be incremented or decremented in units. </dd>
+
+  <dt><a href="ProgressBar2.html">2. Smooth</a></dt>
+  <dd>Demonstrates large and small continuously rotating progress indicators used to indicate a generic &quot;busy&quot; message. </dd>
+
+  <dt><a href="ProgressBar3.html">3. Dialogs</a></dt>
+  <dd>Demonstrates a ProgressDialog, a popup dialog that hosts a progress bar. This example demonstrates both determinate and indeterminate progress indicators. </dd>
+
+  <dt><a href="ProgressBar4.html">4. In Title Bar</a></dt>
+  <dd>Demonstrates an Activity screen with a progress indicator loaded by setting the WindowPolicy's progress indicator feature. </dd>
+</dl>
+
+<h3>Focus</h3>
+<dl>
+  <dt><a href="Focus1.html">1. Vertical</a></dt>
+  <dd>Demonstrates how to block selection of a specific screen element. </dd>
+
+  <dt><a href="Focus2.html">2. Horizontal</a></dt>
+  <dd>Demonstrates how to change the order of which screen element is selected when the user presses arrow keys. </dd>
+  
+  <dt><a href="Focus3.html">3. Circular</a></dt>
+  <dd>Another version of Focus2. </dd>
+</dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/_package.html b/samples/ApiDemos/src/com/example/android/apis/view/_package.html
new file mode 100644
index 0000000..3217336
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/_package.html
@@ -0,0 +1,589 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="assets/style.css" />
+<script type="text/javascript" src="http://www.corp.google.com/style/prettify.js"></script>
+<script src="http://www.corp.google.com/eng/techpubs/include/navbar.js" type="text/javascript"></script>
+
+
+
+</head>
+
+<body>
+
+<p>
+Examples of how to use the android.view and android.widget platform APIs.
+
+For information about view and widget objects, see the topic &quot;Designing
+the UI for an Android application&quot; in the SDK documentation.
+<ol>
+    <li>Layouts
+        <ol>
+            <li>RelativeLayout
+                <ol>
+                    <li>{@link com.android.samples.view.RelativeLayout1
+                        Example 1}</li>
+                    <li>{@link com.android.samples.view.RelativeLayout2
+                        Example 2}</li>
+                </ol>
+            </li>
+            <li>LinearLayout
+                <ol>
+                    <li>{@link com.android.samples.view.LinearLayout1
+                        Example 1}</li>
+                    <li>{@link com.android.samples.view.LinearLayout2 Example
+                        2}</li>
+                    <li>{@link com.android.samples.view.LinearLayout3 Example
+                        3}</li>
+                    <li>{@link com.android.samples.view.LinearLayout4 Example
+                        4}</li>
+                    <li>{@link com.android.samples.view.LinearLayout5 Example
+                        5}</li>
+                    <li>{@link com.android.samples.view.LinearLayout6 Example
+                        6}</li>
+                    <li>{@link com.android.samples.view.LinearLayout7 Example
+                        7}</li>
+                    <li>{@link com.android.samples.view.LinearLayout8 Example
+                        8}</li>
+                </ol>
+            </li>
+            <li>ScrollView
+                <ol>
+                    <li>{@link com.android.samples.view.ScrollView1
+                        Example 1} </li>
+                    <li>{@link com.android.samples.view.ScrollView2 Example
+                        2} </li>
+                </ol>
+            </li>
+            <li>TableLayout
+                <ol>
+                    <li>{@link com.android.samples.view.TableLayout1
+                        Example 1}</li>
+                    <li>{@link com.android.samples.view.TableLayout2 Example
+                        2}</li>
+                    <li>{@link com.android.samples.view.TableLayout3 Example
+                        3}</li>
+                    <li>{@link com.android.samples.view.TableLayout4 Example
+                        4}</li>
+                    <li>{@link com.android.samples.view.TableLayout5 Example
+                        5}</li>
+                    <li>{@link com.android.samples.view.TableLayout6 Example
+                        6}</li>
+                    <li>{@link com.android.samples.view.TableLayout7 Example
+                        7}</li>
+                    <li>{@link com.android.samples.view.TableLayout8 Example
+                        8}</li>
+                    <li>{@link com.android.samples.view.TableLayout9 Example
+                        9}</li>
+                    <li>{@link com.android.samples.view.TableLayout10 Example
+                        10}</li>
+                </ol>
+            </li>
+        </ol>
+    </li>
+    <li>Radio Group
+        <ol>
+            <li>{@link com.android.samples.view.RadioGroup1 Example 1}</li>
+        </ol>
+    </li>
+    <li>ScrollBars
+        <ol>
+            <li>{@link com.android.samples.view.ScrollBar1 Example 1}</li>
+            <li>{@link com.android.samples.view.ScrollBar2 Example 2}</li>
+        </ol>
+    </li>
+    <li>Visibility
+        <ol>
+            <li>{@link com.android.samples.view.Visibility1 Example 1}</li>
+        </ol>
+    </li>
+    <li>Lists
+        <ol>
+            <li>{@link com.android.samples.view.List1 Example 1} </li>
+            <li>{@link com.android.samples.view.List2 Example 2}</li>
+            <li>{@link com.android.samples.view.List3 Example 3}</li>
+            <li>{@link com.android.samples.view.List4 Example 4}</li>
+            <li>{@link com.android.samples.view.List5 Example 5}</li>
+            <li>{@link com.android.samples.view.List6 Example 6}</li>
+            <li>{@link com.android.samples.view.List7 Example 7}</li>
+        </ol>
+    </li>
+    <li>Custom
+        <ol>
+            <li>{@link com.android.samples.view.CustomView1 Example 1}</li>
+        </ol>
+    </li>
+    <li>Gallery
+        <ol>
+            <li>{@link com.android.samples.view.Gallery1 Example 1}</li>
+            <li>{@link com.android.samples.view.Gallery2 Example 2}</li>
+        </ol>
+    </li>
+    <li>Spinner
+        <ol>
+            <li>{@link com.android.samples.view.Spinner1 Example 1}</li>
+        </ol>
+    </li>
+    <li>Grid
+        <ol>
+            <li>{@link com.android.samples.view.Grid1 Example 1}</li>
+        </ol>
+    </li>
+    <li>ImageSwitcher
+        <ol>
+            <li>{@link com.android.samples.view.ImageSwitcher1 Example
+                1}</li>
+        </ol>
+    </li>
+    <li>Animation
+        <ol>
+            <li>{@link com.android.samples.view.Animation1 Example 1}</li>
+            <li>{@link com.android.samples.view.Animation2 Example 1}</li>
+        </ol>
+    </li>
+    <li>Controls
+        <ol>
+            <li>{@link com.android.samples.view.Controls1 Example 1}</li>
+        </ol>
+    </li>
+</ol>
+<p></p>
+
+<h3>LinearLayout Example 1: Stacking Views</h3>
+This example shows a simple use of a LinearLayout. The LinearLayout's height is set to
+<code>android:layout_height="wrap-content"</code>,
+as is the height of each child. Each text view is as tall as it needs
+to be, and the height of the LinearLayout itself is the sum of the height of its children.
+
+<h4>Demo</h4>
+Views/Layouts/LinearLayout/Example 1
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/LinearLayout1.java</a></td>
+            <td class="DescrColumn">Loads the linear_layout_1 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/linear_layout_1.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+
+
+<h3>LinearLayout Example 2: Stacking Views Again</h3>
+In this example, the LinearLayout's height is set
+to <code>android:layout_height="fill-parent"</code>, 
+so the LinearLayout fills the screen. Each text view is as tall as it needs
+to be, so the LinearLayout just stacks them from top to bottom.
+
+<h4>Demo</h4>
+Views/Layouts/LinearLayout/Example 2
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/LinearLayout2.java</a></td>
+            <td class="DescrColumn">Loads the linear_layout_2 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/linear_layout_2.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+
+
+<h3>LinearLayout Example 3: Distributing Extra Space</h3>
+In this example, the LinearLayout's height is set
+to "fill-parent", so the LinearLayout fills the screen. Each text view is as tall as it needs
+to be. However, the middle text view has set <code>android:layout_weight="1"</code>. This means that it
+will get all of the extra space left over after the LinearLayout has sized all of its children.
+
+<h4>Demo</h4>
+Views/Layouts/LinearLayout/Example 3
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/LinearLayout3.java</a></td>
+            <td class="DescrColumn">Loads the linear_layout_3 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/linear_layout_3.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+
+
+<h3>LinearLayout Example 4: Columns</h3>
+This time, the orientation of the LinearLayout is set to horizontal.
+Each of the four child text views has set <code>android:layout_weight="1"</code>
+and <code>android:layout_width="0"</code>.
+This means that each child is initially given a width of 0, and then all of the
+remaining space (the width of the screen) is divided equally among the four
+views.
+
+<h4>Demo</h4>
+Views/Layouts/LinearLayout/Example 4
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/LinearLayout4.java</a></td>
+            <td class="DescrColumn">Loads the linear_layout_4 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/linear_layout_4.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+   		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+
+
+<h3>LinearLayout Example 5: A Simple Form</h3>
+This is a more complete example. It shows:
+<ul>
+	<li>Using nested LinearLayouts (a horizontal layout inside a vertical layout)
+	<li>Using padding on the outer layout
+	<li>Using the <code>layout_gravity</code> attribute to position the horizontal layout
+		on the right side of the screen
+	<li>Using a margin to put some space between buttons
+</ul>
+
+<h4>Demo</h4>
+Views/Layouts/LinearLayout/Example 5
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/LinearLayout5.java</a></td>
+            <td class="DescrColumn">Loads the linear_layout_5 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/linear_layout_5.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+   		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+<h3>RelativeLayout Example 1: Stretching</h3>
+There are three views in this example. The first view (view1) is pinned to the top of the screen through the use of this
+attribute: <code>android:layout_alignParentTop="true"</code>. 
+The second view (view2) is pinned to the bottom of the screen: <code>android:layout_alignParentBottom="true"</code>.
+This demonstrates how views can be positioned relative to the RelativeLayout itself.
+
+<p>Views can also be positioned relative to each other as well. In this example, view3 is below view1 and above
+view2: <code>android:layout_above="view2" android:layout_below="view1"</code>. This has the effect of making 
+view3 stretch between view1 and view2.</p> 
+
+<p>Note that since view3 depends on the positions of both view1 and view2, it is defined after them in the layout
+file.</p> 
+
+<h4>Demo</h4>
+Views/Layouts/RelativeLayout/Example 1
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/RelativeLayout1.java</a></td>
+            <td class="DescrColumn">Loads the relative_layout_1 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/relative_layout_1.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+<h3>RelativeLayout Example 2: A Simple Form Revisited</h3>
+The form created in LinearLayout Example 5 is recreated using a RelativeLayout. This example demonstrates:
+
+<ul>
+	<li>Using padding on the outer layout
+	<li>Positioning views realtive to one another using the <code>android:layout_below</code> and 
+	<code>android:layout_below</code> and <code>android:layout_toLeft<code> attributes.
+	<li>Aligning the top edges of the buttons with the <code>android:layout_alignTop<code> attribute
+	<li>Right-aligning the OK button with <code>android:layout_alignParentRight</code>
+	<li>Using a margin to put some space between buttons
+</ul>
+
+<h4>Demo</h4>
+Views/Layouts/RelativeLayout/Example 2
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/RelativeLayout2.java</a></td>
+            <td class="DescrColumn">Loads the relative_layout_2 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/relative_layout_2.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+<h3>Scrolling Example 1</h3>
+All of the layout classes discussed above do not scroll. 
+They simply arrange their children within whatever space is made available to them.
+
+<p>The ScrollView is used to implement vertical scrolling. It does not display any
+content of its own. Instead, it assumes it has one child and pans up and down to keep
+the interesting area of its child in view.</p>
+
+<p>In this example, a ScrollView is used to wrap a LinearLayout. The LinearLayout
+in turn contains a stack of TextViews and Buttons. The ScrollView is as wide as 
+the screen (<code>android:layout_width="fill-parent"</code>) and tall enough to 
+wrap the LinearLayout (<code>android:layout_height="wrap-content"</code>). The 
+LinearLayout uses the same parameters, so it is also as wide as the screen and is as
+tall as the sum of the heigts of all of its children.</p>
+
+<h4>Demo</h4>
+Views/Layouts/ScrollView/Example 1
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/ScrollView1.java</a></td>
+            <td class="DescrColumn">Loads the scroll_view_1 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/scroll_view_1.xml</a></td>
+            <td class="DescrColumn">Defines the layout</td>
+        </tr>
+ 		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>       
+</table>
+<h2><a name="Lists">Lists</a></h2>
+<h3>ListView Example 1: A "Hello World" List</h3>
+
+ListViews are used to display vertically scrolling list of information. Unlike the ScrollView, which pans up and 
+down through a set of views that have already been built, the ListView is "virtualized", meaning that views are 
+created only as necessary in order to display what is actually on the screen. ListViews can thus be used to 
+efficiently display very large sets of data. (In this example, the list displays over 600 kinds of cheese.) 
+
+<p>ListViews are highly customizable: you can change where the underlying data comes from, the internal
+representation of the data, and the Views that are used to display the data on the screen. All of this is 
+done with a ListAdapter class. The Android platform includes some ListAdapters that are ready to use, or 
+you can make your own to display custom information. (See ListView Example 4 and ListView Example 5.)</p>
+
+<p>This example uses an existing ListAdapter called ArrayListAdapter. This adapter uses generics to map
+an array of objects to TextViews. In this case we are using an array of Strings.</p>
+
+<p>Note that this example does not have a layout file. This is because the List1 class derives from 
+ListScreen, which will provide a default layout if your activity does not provide an override.</p>
+
+<h4>Demo</h4>
+Views/Lists/Example 1
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/List1.java</a></td>
+            <td class="DescrColumn">Contains code for the List1 class</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+<h3>ListView Example 2: Displaying Data from a Cursor </h3>
+
+It is very common to display data from a database in a ListView. The easiest way to do this is to use a 
+SimpleCursorListAdapter. This is a class that will get data from a Cursor and display the data in 
+each row in Views defined in an XML template.
+
+<p>In this example, the SimpleCursorListAdapter is provided with a cursor that contains a list of all 
+people. Each row will be displayed using the Views defined in this XL file: 
+<a href="" onClick="findCode(this)">//device/apps/common/assets/res/any/layout/simple_list_item_1.xml</a>.
+</p>
+
+<p>When creating a SimpleCursorListAdapter, you also provide a mapping from column names in the 
+Cursor to view ids in the template file. In this case we are mapping the People.NAME column to the
+"text1" TextView.
+</p>
+
+<h4>Demo</h4>
+Views/Lists/Example 2
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/List2.java</a></td>
+            <td class="DescrColumn">Contains code for the List2 class</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/apps/common/assets/res/any/layout/simple_list_item_1.xml</a></td>
+            <td class="DescrColumn">Defines the XML template used for each row. 
+            (Note that this file is provided as part of the Android platform.)</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+<h3>ListView Example 3: Displaying Data from a Cursor, Fancier Version </h3>
+
+This example extends the idea presented in Example 2. Instead of just presenting a list of names, though,
+it shows two lines of information for the selected item (name and phone number). It shows just the name for unselected items. 
+
+<p>
+This example still uses a SimpleCursorListAdapter, but changes the following:</p>
+
+<ul>
+	<li>The Cursor now contains all phone numbers
+	<li>It uses a different template for each row: <a href="" onClick="findCode(this)">//device/apps/common/assets/res/any/layout/simple_list_item_2.xml</a>
+	<li>Since simple_list_item_2.xml contains two views, were mapping two columns 
+	<code>{ Phones.NAME, Phones.NUMBER }</code> to the two views 
+	<code>{ "text1", "text2"}</code>
+	<li>The simple_list_item_2.xml uses a TwoLineListItem view, which is a subclass of LinearLayout that knows to only show
+	the second item when it is selected.
+</ul>
+
+<h4>Demo</h4>
+Views/Lists/Example 3
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/List3.java</a></td>
+            <td class="DescrColumn">Contains code for the List3 class</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/apps/common/assets/res/any/layout/simple_list_item_2.xml</a></td>
+            <td class="DescrColumn">Defines the XML template used for each row. 
+            (Note that this file is provided as part of the Android platform.)</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+
+<h3>ListView Example 4: Writing a Custom ListAdapter </h3>
+
+The previous examples all used standard ListAdapters. It is also possible to write your own ListAdapters 
+to access data from custom sources.
+
+<p>
+This example introduces a SongListAdapter, which gets its data from an array of titles and an array of lyrics. 
+The SongListAdapter then produces a SongView which is capable of displaying this data.
+</p>  
+
+<p>
+This example also shows how the ListView handles scrolling large items.
+
+<h4>Demo</h4>
+Views/Lists/Example 4
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/List4.java</a></td>
+            <td class="DescrColumn">Contains code for the List4 class, along with a custom ListAdapter and custom View to display the data.</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+
+
+<h3>ListView Example 5: List Separators </h3>
+
+ListView supports the concept of non-selectable "separators" between items. The ListView delegated to its ListAdapter the
+task of deciding whether a given position in the list is a separator or selectable data.
+
+<p><i>This example needs some cleanup.</i></p>
+
+<h4>Demo</h4>
+Views/Lists/Example 5
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/List5.java</a></td>
+            <td class="DescrColumn">Contains code for the List5 class, along with a custom ListAdapter.</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+
+<h2><a name="Working">Working with Views</a></h2>
+
+<h3>Custom View Example 1: LabelView</h3>
+
+
+
+<p>
+Note: This example does not support multi-line or right-to-left text. It is sample code only
+and should not be used in place of the TextView.
+</p>
+
+
+<h4>Demo</h4>
+Views/Custom/Example 1
+ 
+<h4>Source files</h4>
+<table class="LinkTable">
+        <tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/CustomView1.java</a></td>
+            <td class="DescrColumn">Loads the custom_view_3 layout resource</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/src/com/android/sdk/view/LabelView.java</a></td>
+            <td class="DescrColumn">Implementation of the custom view</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/assets/res/any/layout/custom_view_1.xml</a></td>
+            <td class="DescrColumn">Defines a layout that uses LabelViews</td>
+        </tr>
+		<tr>
+            <td class="LinkColumn"><a href="" onClick="findCode(this)">//device/samples/SampleCode/AndroidManifest.xml</a></td>
+            <td class="DescrColumn">Defines the activity</td>
+        </tr>
+</table>
+</body>
+</html>
diff --git a/samples/ApiDemos/tests/Android.mk b/samples/ApiDemos/tests/Android.mk
new file mode 100644
index 0000000..f975662
--- /dev/null
+++ b/samples/ApiDemos/tests/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Notice that we don't have to include the src files of ApiDemos because, by
+# running the tests using an instrumentation targeting ApiDemos, we
+# automatically get all of its classes loaded into our environment.
+
+LOCAL_PACKAGE_NAME := ApiDemosTests
+
+LOCAL_INSTRUMENTATION_FOR := ApiDemos
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
diff --git a/samples/ApiDemos/tests/AndroidManifest.xml b/samples/ApiDemos/tests/AndroidManifest.xml
new file mode 100644
index 0000000..084c88d
--- /dev/null
+++ b/samples/ApiDemos/tests/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.apis.tests">
+
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--
+    This declares that this app uses the instrumentation test runner targeting
+    the package of com.example.android.apis.  To run the tests use the command:
+    "adb shell am instrument -w com.example.android.apis.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.example.android.apis"
+                     android:label="Tests for Api Demos."/>
+
+</manifest>
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/AllTests.java b/samples/ApiDemos/tests/src/com/example/android/apis/AllTests.java
new file mode 100644
index 0000000..edacb47
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/AllTests.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 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;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import android.test.suitebuilder.TestSuiteBuilder;
+
+/**
+ * A test suite containing all tests for ApiDemos.
+ *
+ * To run all suites found in this apk:
+ * $ adb shell am instrument -w \
+ *   com.example.android.apis.tests/android.test.InstrumentationTestRunner
+ *
+ * To run just this suite from the command line:
+ * $ adb shell am instrument -w \
+ *   -e class com.example.android.apis.AllTests \
+ *   com.example.android.apis.tests/android.test.InstrumentationTestRunner
+ *
+ * To run an individual test case, e.g. {@link com.example.android.apis.os.MorseCodeConverterTest}:
+ * $ adb shell am instrument -w \
+ *   -e class com.example.android.apis.os.MorseCodeConverterTest \
+ *   com.example.android.apis.tests/android.test.InstrumentationTestRunner
+ *
+ * To run an individual test, e.g. {@link com.example.android.apis.os.MorseCodeConverterTest#testCharacterS()}:
+ * $ adb shell am instrument -w \
+ *   -e class com.example.android.apis.os.MorseCodeConverterTest#testCharacterS \
+ *   com.example.android.apis.tests/android.test.InstrumentationTestRunner
+ */
+public class AllTests extends TestSuite {
+
+    public static Test suite() {
+        return new TestSuiteBuilder(AllTests.class)
+                .includeAllPackagesUnderHere()
+                .build();
+    }
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/ApiDemosApplicationTests.java b/samples/ApiDemos/tests/src/com/example/android/apis/ApiDemosApplicationTests.java
new file mode 100644
index 0000000..3074ca6
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/ApiDemosApplicationTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 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;
+
+import android.test.ApplicationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * This is a simple framework for a test of an Application.  See 
+ * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on 
+ * how to write and extend Application tests.
+ * 
+ * To run this test, you can type:
+ * adb shell am instrument -w \
+ *   -e class com.example.android.apis.ApiDemosApplicationTests \
+ *   com.example.android.apis.tests/android.test.InstrumentationTestRunner
+ */
+public class ApiDemosApplicationTests extends ApplicationTestCase<ApiDemosApplication> {
+
+    public ApiDemosApplicationTests() {
+        super(ApiDemosApplication.class);
+      }
+
+      @Override
+      protected void setUp() throws Exception {
+          super.setUp();
+      }
+
+      /**
+       * The name 'test preconditions' is a convention to signal that if this
+       * test doesn't pass, the test case was not set up properly and it might
+       * explain any and all failures in other tests.  This is not guaranteed
+       * to run before other tests, as junit uses reflection to find the tests.
+       */
+      @SmallTest
+      public void testPreconditions() {
+      }
+      
+      /**
+       * Test basic startup/shutdown of Application
+       */
+      @MediumTest
+      public void testSimpleCreate() {
+          createApplication(); 
+      }
+      
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/ApiDemosTest.java b/samples/ApiDemos/tests/src/com/example/android/apis/ApiDemosTest.java
new file mode 100644
index 0000000..0103da8
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/ApiDemosTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 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;
+
+import android.test.ActivityInstrumentationTestCase;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityInstrumentationTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class ApiDemosTest extends ActivityInstrumentationTestCase<ApiDemos> {
+
+    public ApiDemosTest() {
+        super("com.example.android.apis", ApiDemos.class);
+    }
+
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/app/ForwardingTest.java b/samples/ApiDemos/tests/src/com/example/android/apis/app/ForwardingTest.java
new file mode 100644
index 0000000..340bedb
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/app/ForwardingTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+import com.example.android.apis.view.Focus2ActivityTest;
+
+import android.content.Context;
+import android.content.Intent;
+import android.test.ActivityUnitTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+
+/**
+ * This demonstrates completely isolated "unit test" of an Activity class.
+ *
+ * <p>This model for testing creates the entire Activity (like {@link Focus2ActivityTest}) but does
+ * not attach it to the system (for example, it cannot launch another Activity).  It allows you to
+ * inject additional behaviors via the 
+ * {@link android.test.ActivityUnitTestCase#setActivityContext(Context)} and 
+ * {@link android.test.ActivityUnitTestCase#setApplication(android.app.Application)} methods.  
+ * It also allows you to more carefully test your Activity's performance 
+ * Writing unit tests in this manner requires more care and attention, but allows you to test
+ * very specific behaviors, and can also be an easier way to test error conditions.
+ * 
+ * <p>Because ActivityUnitTestCase creates the Activity under test completely outside of
+ * the usual system, tests of layout and point-click UI interaction are much less useful
+ * in this configuration.  It's more useful here to concentrate on tests that involve the 
+ * underlying data model, internal business logic, or exercising your Activity's life cycle.
+ *
+ * <p>See {@link com.example.android.apis.AllTests} for documentation on running
+ * all tests and individual tests in this application.
+ */
+public class ForwardingTest extends ActivityUnitTestCase<Forwarding> {
+
+    private Intent mStartIntent;
+    private Button mButton;
+
+    public ForwardingTest() {
+        super(Forwarding.class);
+      }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // In setUp, you can create any shared test data, or set up mock components to inject
+        // into your Activity.  But do not call startActivity() until the actual test methods.
+        mStartIntent = new Intent(Intent.ACTION_MAIN);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        startActivity(mStartIntent, null, null);
+        mButton = (Button) getActivity().findViewById(R.id.go);
+        
+        assertNotNull(getActivity());
+        assertNotNull(mButton);
+    }
+    
+    /**
+     * This test demonstrates examining the way that activity calls startActivity() to launch 
+     * other activities.
+     */
+    @MediumTest
+    public void testSubLaunch() {
+        Forwarding activity = startActivity(mStartIntent, null, null);
+        mButton = (Button) activity.findViewById(R.id.go);
+        
+        // This test confirms that when you click the button, the activity attempts to open
+        // another activity (by calling startActivity) and close itself (by calling finish()).
+        mButton.performClick();
+        
+        assertNotNull(getStartedActivityIntent());
+        assertTrue(isFinishCalled());
+    }
+    
+    /**
+     * This test demonstrates ways to exercise the Activity's life cycle.
+     */
+    @MediumTest
+    public void testLifeCycleCreate() {
+        Forwarding activity = startActivity(mStartIntent, null, null);
+        
+        // At this point, onCreate() has been called, but nothing else
+        // Complete the startup of the activity
+        getInstrumentation().callActivityOnStart(activity);
+        getInstrumentation().callActivityOnResume(activity);
+        
+        // At this point you could test for various configuration aspects, or you could 
+        // use a Mock Context to confirm that your activity has made certain calls to the system
+        // and set itself up properly.
+        
+        getInstrumentation().callActivityOnPause(activity);
+        
+        // At this point you could confirm that the activity has paused properly, as if it is
+        // no longer the topmost activity on screen.
+        
+        getInstrumentation().callActivityOnStop(activity);
+        
+        // At this point, you could confirm that the activity has shut itself down appropriately,
+        // or you could use a Mock Context to confirm that your activity has released any system
+        // resources it should no longer be holding.
+
+        // ActivityUnitTestCase.tearDown(), which is always automatically called, will take care
+        // of calling onDestroy().
+    }
+
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/app/LocalServiceTest.java b/samples/ApiDemos/tests/src/com/example/android/apis/app/LocalServiceTest.java
new file mode 100644
index 0000000..78fee41
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/app/LocalServiceTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.app;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.test.MoreAsserts;
+import android.test.ServiceTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * This is a simple framework for a test of a Service.  See {@link android.test.ServiceTestCase
+ * ServiceTestCase} for more information on how to write and extend service tests.
+ * 
+ * To run this test, you can type:
+ * adb shell am instrument -w \
+ *   -e class com.example.android.apis.app.LocalServiceTest \
+ *   com.example.android.apis.tests/android.test.InstrumentationTestRunner
+ */
+public class LocalServiceTest extends ServiceTestCase<LocalService> {
+
+    public LocalServiceTest() {
+      super(LocalService.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @SmallTest
+    public void testPreconditions() {
+    }
+    
+    /**
+     * Test basic startup/shutdown of Service
+     */
+    @SmallTest
+    public void testStartable() {
+        Intent startIntent = new Intent();
+        startIntent.setClass(getContext(), LocalService.class);
+        startService(startIntent); 
+    }
+    
+    /**
+     * Test binding to service
+     */
+    @MediumTest
+    public void testBindable() {
+        Intent startIntent = new Intent();
+        startIntent.setClass(getContext(), LocalService.class);
+        IBinder service = bindService(startIntent); 
+    }
+    
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/os/MorseCodeConverterTest.java b/samples/ApiDemos/tests/src/com/example/android/apis/os/MorseCodeConverterTest.java
new file mode 100644
index 0000000..7cf0395
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/os/MorseCodeConverterTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.os;
+
+import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * An example of a true unit test that tests the utility class {@link MorseCodeConverter}.
+ * Since this test doesn't need a {@link android.content.Context}, or any other
+ * dependencies injected, it simply extends the standard {@link TestCase}.
+ *
+ * See {@link com.example.android.apis.AllTests} for documentation on running
+ * all tests and individual tests in this application.
+ */
+public class MorseCodeConverterTest extends TestCase {
+
+    @SmallTest
+    public void testCharacterS() throws Exception {
+
+        long[] expectedBeeps = {
+                MorseCodeConverter.DOT,
+                MorseCodeConverter.DOT,
+                MorseCodeConverter.DOT,
+                MorseCodeConverter.DOT,
+                MorseCodeConverter.DOT};
+        long[] beeps = MorseCodeConverter.pattern('s');
+
+        assertArraysEqual(expectedBeeps, beeps);
+    }
+
+    private void assertArraysEqual(long[] expected, long[] actual) {
+        assertEquals("Unexpected array length.", expected.length, actual.length);
+        for (int i = 0; i < expected.length; i++) {
+            long expectedLong = expected[i];
+            long actualLong = actual[i];
+            assertEquals("Unexpected long at index: " + i, expectedLong, actualLong);
+        }
+    }
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/view/Focus2ActivityTest.java b/samples/ApiDemos/tests/src/com/example/android/apis/view/Focus2ActivityTest.java
new file mode 100644
index 0000000..91f712f
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/view/Focus2ActivityTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008 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.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+
+/**
+ * An example of an {@link ActivityInstrumentationTestCase} of a specific activity {@link Focus2}.
+ * By virtue of extending {@link ActivityInstrumentationTestCase}, the target activity is automatically
+ * launched and finished before and after each test.  This also extends
+ * {@link android.test.InstrumentationTestCase}, which provides
+ * access to methods for sending events to the target activity, such as key and
+ * touch events.  See {@link #sendKeys}.
+ *
+ * In general, {@link android.test.InstrumentationTestCase}s and {@link ActivityInstrumentationTestCase}s
+ * are heavier weight functional tests available for end to end testing of your
+ * user interface.  When run via a {@link android.test.InstrumentationTestRunner},
+ * the necessary {@link android.app.Instrumentation} will be injected for you to
+ * user via {@link #getInstrumentation} in your tests.
+ *
+ * See {@link com.example.android.apis.app.ForwardingTest} for an example of an Activity unit test.
+ *
+ * See {@link com.example.android.apis.AllTests} for documentation on running
+ * all tests and individual tests in this application.
+ */
+public class Focus2ActivityTest extends ActivityInstrumentationTestCase<Focus2> {
+
+    private Button mLeftButton;
+    private Button mCenterButton;
+    private Button mRightButton;
+
+
+    public Focus2ActivityTest() {
+        super("com.example.android.apis", Focus2.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Focus2 a = getActivity();
+        mLeftButton = (Button) a.findViewById(R.id.leftButton);
+        mCenterButton = (Button) a.findViewById(R.id.centerButton);
+        mRightButton = (Button) a.findViewById(R.id.rightButton);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertTrue("center button should be right of left button",
+                mLeftButton.getRight() < mCenterButton.getLeft());
+        assertTrue("right button should be right of center button",
+                mCenterButton.getRight() < mRightButton.getLeft());
+        assertTrue("left button should be focused", mLeftButton.isFocused());
+    }
+
+    @MediumTest
+    public void testGoingRightFromLeftButtonJumpsOverCenterToRight() {
+        sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+        assertTrue("right button should be focused", mRightButton.isFocused());
+    }
+
+    @MediumTest
+    public void testGoingLeftFromRightButtonGoesToCenter()  {
+        // Give right button focus by having it request focus.  We post it
+        // to the UI thread because we are not running on the same thread, and
+        // any direct api calls that change state must be made from the UI thread.
+        // This is in contrast to instrumentation calls that send events that are
+        // processed through the framework and eventually find their way to
+        // affecting the ui thread.
+        getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                mRightButton.requestFocus();
+            }
+        });
+        // wait for the request to go through
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(mRightButton.isFocused());
+
+        sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
+        assertTrue("center button should be focused", mCenterButton.isFocused());
+    }
+}
diff --git a/samples/ApiDemos/tests/src/com/example/android/apis/view/Focus2AndroidTest.java b/samples/ApiDemos/tests/src/com/example/android/apis/view/Focus2AndroidTest.java
new file mode 100644
index 0000000..b52e4b8
--- /dev/null
+++ b/samples/ApiDemos/tests/src/com/example/android/apis/view/Focus2AndroidTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 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.content.Context;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.FocusFinder;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+/**
+ * This exercises the same logic as {@link Focus2ActivityTest} but in a lighter
+ * weight manner; it doesn't need to launch the activity, and it can test the
+ * focus behavior by calling {@link FocusFinder} methods directly.
+ *
+ * {@link Focus2ActivityTest} is still useful to verify that, at an end to end
+ * level, key events actually translate to focus transitioning in the way we expect.
+ * A good complementary way to use both types of tests might be to have more exhaustive
+ * coverage in the lighter weight test case, and a few end to end scenarios in the
+ * functional {@link android.test.ActivityInstrumentationTestCase}.  This would provide reasonable
+ * assurance that the end to end system is working, while avoiding the overhead of
+ * having every corner case exercised in the slower, heavier weight way.
+ *
+ * Even as a lighter weight test, this test still needs access to a {@link Context}
+ * to inflate the file, which is why it extends {@link AndroidTestCase}.
+ * 
+ * If you ever need a context to do your work in tests, you can extend
+ * {@link AndroidTestCase}, and when run via an {@link android.test.InstrumentationTestRunner},
+ * the context will be injected for you.
+ * 
+ * See {@link com.example.android.apis.app.ForwardingTest} for an example of an Activity unit test.
+ *
+ * See {@link com.example.android.apis.AllTests} for documentation on running
+ * all tests and individual tests in this application.
+ */
+public class Focus2AndroidTest extends AndroidTestCase {
+
+    private FocusFinder mFocusFinder;
+
+    private ViewGroup mRoot;
+
+    private Button mLeftButton;
+    private Button mCenterButton;
+    private Button mRightButton;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mFocusFinder = FocusFinder.getInstance();
+
+        // inflate the layout
+        final Context context = getContext();
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        mRoot = (ViewGroup) inflater.inflate(R.layout.focus_2, null);
+
+        // manually measure it, and lay it out
+        mRoot.measure(500, 500);
+        mRoot.layout(0, 0, 500, 500);
+
+        mLeftButton = (Button) mRoot.findViewById(R.id.leftButton);
+        mCenterButton = (Button) mRoot.findViewById(R.id.centerButton);
+        mRightButton = (Button) mRoot.findViewById(R.id.rightButton);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @SmallTest
+    public void testPreconditions() {
+        assertNotNull(mLeftButton);
+        assertTrue("center button should be right of left button",
+                mLeftButton.getRight() < mCenterButton.getLeft());
+        assertTrue("right button should be right of center button",
+                mCenterButton.getRight() < mRightButton.getLeft());
+    }
+
+    @SmallTest
+    public void testGoingRightFromLeftButtonJumpsOverCenterToRight() {
+        assertEquals("right should be next focus from left",
+                mRightButton,
+                mFocusFinder.findNextFocus(mRoot, mLeftButton, View.FOCUS_RIGHT));
+    }
+
+    @SmallTest
+    public void testGoingLeftFromRightButtonGoesToCenter() {
+        assertEquals("center should be next focus from right",
+                mCenterButton,
+                mFocusFinder.findNextFocus(mRoot, mRightButton, View.FOCUS_LEFT));
+    }
+}
diff --git a/samples/Compass/Android.mk b/samples/Compass/Android.mk
new file mode 100644
index 0000000..9434582
--- /dev/null
+++ b/samples/Compass/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 := Compass
+
+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/Compass/AndroidManifest.xml b/samples/Compass/AndroidManifest.xml
new file mode 100644
index 0000000..9aa5636
--- /dev/null
+++ b/samples/Compass/AndroidManifest.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+
+<!-- This file describes the code in the Compass package, which is
+     used by the system to determine how to start your application and
+     integrate it with the rest of the system.  -->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.compass">
+
+    <!-- This package contains an application...  The 'label' is the name
+         to display to the user for the overall application, and provides
+         a default label for all following components.  The syntax here is a
+         reference to one of our string resources.-->
+    <application android:label="@string/compass_app">
+
+        <!-- An Activity in the application - this is something the user
+             can launch and interact with.  The "name" attribute is the
+             name of the class within your package that implements this
+             activity. -->
+        <activity android:name="CompassActivity">
+
+            <!-- An IntentFilter tells the system when it should use your
+                 activity.  This allows the user to get to your activity
+                 without someone having to explicitly know to launch your
+                 class "com.example.android.compass_app.CompassActivity". -->
+            <intent-filter>
+                <!-- The MAIN action describes a main entry point into an
+                     activity, without any associated data. -->
+                <action android:name="android.intent.action.MAIN" />
+
+                <!-- This places this activity into the main app list. -->
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/samples/Compass/res/values/strings.xml b/samples/Compass/res/values/strings.xml
new file mode 100644
index 0000000..7cf3da4
--- /dev/null
+++ b/samples/Compass/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="compass_app">Compass</string>
+</resources>
+
diff --git a/samples/Compass/src/com/example/android/compass/CompassActivity.java b/samples/Compass/src/com/example/android/compass/CompassActivity.java
new file mode 100644
index 0000000..c4b9566
--- /dev/null
+++ b/samples/Compass/src/com/example/android/compass/CompassActivity.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2008 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.compass;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+import static javax.microedition.khronos.opengles.GL10.*;
+
+import android.app.Activity;
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * This class provides a basic demonstration of how to use the
+ * {@link android.hardware.SensorManager SensorManager} API to draw
+ * a 3D compass.
+ */
+public class CompassActivity extends Activity implements Renderer, SensorEventListener {
+    private GLSurfaceView mGLSurfaceView;
+    private SensorManager mSensorManager;
+    private float[] mGData = new float[3];
+    private float[] mMData = new float[3];
+    private float[] mR = new float[16];
+    private float[] mI = new float[16];
+    private FloatBuffer mVertexBuffer;
+    private FloatBuffer mColorBuffer;
+    private ByteBuffer mIndexBuffer;
+    private float[] mOrientation = new float[3];
+    private int mCount;
+
+    public CompassActivity() {
+    }
+
+    /** Called with the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
+        mGLSurfaceView = new GLSurfaceView(this);
+        mGLSurfaceView.setRenderer(this);
+        setContentView(mGLSurfaceView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mGLSurfaceView.onResume();
+        Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+        mSensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_GAME);
+        mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_GAME);
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mGLSurfaceView.onPause();
+        mSensorManager.unregisterListener(this);
+    }
+
+    public int[] getConfigSpec() {
+        // We want a depth buffer, don't care about the
+        // details of the color buffer.
+        int[] configSpec = {
+                EGL10.EGL_DEPTH_SIZE,   16,
+                EGL10.EGL_NONE
+        };
+        return configSpec;
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(0, 0, -2);
+
+        /*
+         * All the magic happens here. The rotation matrix mR reported by
+         * SensorManager.getRotationMatrix() is a 4x4 row-major matrix.
+         * We need to use its inverse for rendering. The inverse is
+         * simply calculated by taking the matrix' transpose. However, since
+         * glMultMatrixf() expects a column-major matrix, we can use mR
+         * directly!
+         */
+        gl.glMultMatrixf(mR, 0);
+        // some test code which will be used/cleaned up before we ship this.
+        //gl.glMultMatrixf(mI, 0);
+
+        gl.glVertexPointer(3, GL_FLOAT, 0, mVertexBuffer);
+        gl.glColorPointer(4, GL_FLOAT, 0, mColorBuffer);
+        gl.glDrawElements(GL_LINES, 6, GL_UNSIGNED_BYTE, mIndexBuffer);
+    }
+
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+        gl.glViewport(0, 0, width, height);
+
+        /*
+         * Set our projection matrix. This doesn't have to be done
+         * each time we draw, but usually a new projection needs to
+         * be set when the viewport is resized.
+         */
+
+        float ratio = (float) width / height;
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+        gl.glClearColor(1,1,1,1);
+        gl.glEnable(GL10.GL_CULL_FACE);
+        gl.glShadeModel(GL10.GL_SMOOTH);
+        gl.glEnable(GL10.GL_DEPTH_TEST);
+
+        /*
+         * create / load the our 3D models here
+         */
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+        float vertices[] = {
+                0,0,0,
+                1,0,0,
+                0,1,0,
+                0,0,1
+        };
+        float colors[] = {
+                0,0,0,0,
+                1,0,0,1,
+                0,1,0,1,
+                0,0,1,1
+        };
+        byte indices[] = { 0, 1, 0, 2, 0, 3 };
+
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct, i.e., they must be placed on the
+        // native heap where the garbage collector cannot
+        // move them.
+        //
+        // Buffers with multi-byte datatypes (e.g., short, int, float)
+        // must have their byte order set to native order
+
+        ByteBuffer vbb;
+        vbb = ByteBuffer.allocateDirect(vertices.length*4);
+        vbb.order(ByteOrder.nativeOrder());
+        mVertexBuffer = vbb.asFloatBuffer();
+        mVertexBuffer.put(vertices);
+        mVertexBuffer.position(0);
+
+        vbb = ByteBuffer.allocateDirect(colors.length*4);
+        vbb.order(ByteOrder.nativeOrder());
+        mColorBuffer = vbb.asFloatBuffer();
+        mColorBuffer.put(colors);
+        mColorBuffer.position(0);
+
+        mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
+        mIndexBuffer.put(indices);
+        mIndexBuffer.position(0);
+    }
+
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    }
+
+    public void onSensorChanged(SensorEvent event) {
+        int type = event.sensor.getType();
+        float[] data;
+        if (type == Sensor.TYPE_ACCELEROMETER) {
+            data = mGData;
+        } else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
+            data = mMData;
+        } else {
+            // we should not be here.
+            return;
+        }
+        for (int i=0 ; i<3 ; i++)
+            data[i] = event.values[i];
+
+        SensorManager.getRotationMatrix(mR, mI, mGData, mMData);
+// some test code which will be used/cleaned up before we ship this.
+//        SensorManager.remapCoordinateSystem(mR,
+//                SensorManager.AXIS_X, SensorManager.AXIS_Z, mR);
+//        SensorManager.remapCoordinateSystem(mR,
+//                SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, mR);
+        SensorManager.getOrientation(mR, mOrientation);
+        float incl = SensorManager.getInclination(mI);
+
+        if (mCount++ > 50) {
+            final float rad2deg = (float)(180.0f/Math.PI);
+            mCount = 0;
+            Log.d("Compass", "yaw: " + (int)(mOrientation[0]*rad2deg) +
+                    "  pitch: " + (int)(mOrientation[1]*rad2deg) +
+                    "  roll: " + (int)(mOrientation[2]*rad2deg) +
+                    "  incl: " + (int)(incl*rad2deg)
+                    );
+        }
+    }
+}
diff --git a/samples/GlobalTime/Android.mk b/samples/GlobalTime/Android.mk
new file mode 100644
index 0000000..deb82f5
--- /dev/null
+++ b/samples/GlobalTime/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GlobalTime
+
+include $(BUILD_PACKAGE)
diff --git a/samples/GlobalTime/AndroidManifest.xml b/samples/GlobalTime/AndroidManifest.xml
new file mode 100644
index 0000000..7aee91b
--- /dev/null
+++ b/samples/GlobalTime/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.globaltime">
+    <application android:icon="@drawable/app_global_time"
+            android:label="Global Time">
+        <activity android:name="GlobalTime"
+                android:theme="@style/Theme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />                                            
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/GlobalTime/MODULE_LICENSE_APACHE2 b/samples/GlobalTime/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/GlobalTime/MODULE_LICENSE_APACHE2
diff --git a/samples/GlobalTime/NOTICE b/samples/GlobalTime/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/samples/GlobalTime/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/samples/GlobalTime/assets/cities_en.dat b/samples/GlobalTime/assets/cities_en.dat
new file mode 100644
index 0000000..c982ef4
--- /dev/null
+++ b/samples/GlobalTime/assets/cities_en.dat
Binary files differ
diff --git a/samples/GlobalTime/assets/earth.raw b/samples/GlobalTime/assets/earth.raw
new file mode 100644
index 0000000..f884e75
--- /dev/null
+++ b/samples/GlobalTime/assets/earth.raw
Binary files differ
diff --git a/samples/GlobalTime/assets/lights.dat b/samples/GlobalTime/assets/lights.dat
new file mode 100644
index 0000000..14d4f36
--- /dev/null
+++ b/samples/GlobalTime/assets/lights.dat
Binary files differ
diff --git a/samples/GlobalTime/assets/tz512.raw b/samples/GlobalTime/assets/tz512.raw
new file mode 100644
index 0000000..3ce1d5c
--- /dev/null
+++ b/samples/GlobalTime/assets/tz512.raw
Binary files differ
diff --git a/samples/GlobalTime/assets/world.gles b/samples/GlobalTime/assets/world.gles
new file mode 100644
index 0000000..815db1e
--- /dev/null
+++ b/samples/GlobalTime/assets/world.gles
Binary files differ
diff --git a/samples/GlobalTime/res/drawable/app_global_time.png b/samples/GlobalTime/res/drawable/app_global_time.png
new file mode 100644
index 0000000..914977d
--- /dev/null
+++ b/samples/GlobalTime/res/drawable/app_global_time.png
Binary files differ
diff --git a/samples/GlobalTime/res/layout/global_time.xml b/samples/GlobalTime/res/layout/global_time.xml
new file mode 100644
index 0000000..237207f
--- /dev/null
+++ b/samples/GlobalTime/res/layout/global_time.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.
+-->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:textSize="18sp"
+    android:text="@string/global_time_text_text" />
+
+
diff --git a/samples/GlobalTime/res/values/strings.xml b/samples/GlobalTime/res/values/strings.xml
new file mode 100644
index 0000000..d35c059
--- /dev/null
+++ b/samples/GlobalTime/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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>
+
+    <string name="global_time_text_text">Global Time</string>
+
+</resources>
diff --git a/samples/GlobalTime/res/values/styles.xml b/samples/GlobalTime/res/values/styles.xml
new file mode 100644
index 0000000..6051f0f
--- /dev/null
+++ b/samples/GlobalTime/res/values/styles.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/Calendar/assets/res/any/styles.xml
+**
+** Copyright 2006, 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="Theme" parent="android:Theme.Black">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowBackground">@null</item>
+        <!-- <item name="android:windowFrame">@null</item> -->
+    </style>
+</resources>
diff --git a/samples/GlobalTime/src/com/android/globaltime/Annulus.java b/samples/GlobalTime/src/com/android/globaltime/Annulus.java
new file mode 100644
index 0000000..b811d88
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/Annulus.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A class that draws a ring with a given center and inner and outer radii.
+ * The inner and outer rings each have a color and the remaining pixels are
+ * colored by interpolation.  GlobalTime uses this class to simulate an
+ * "atmosphere" around the earth.
+ */
+public class Annulus extends Shape {
+
+    /**
+     * Constructs an annulus.
+     * 
+     * @param centerX the X coordinate of the center point
+     * @param centerY the Y coordinate of the center point
+     * @param Z the fixed Z for the entire ring
+     * @param innerRadius the inner radius
+     * @param outerRadius the outer radius
+     * @param rInner the red channel of the color of the inner ring
+     * @param gInner the green channel of the color of the inner ring
+     * @param bInner the blue channel of the color of the inner ring
+     * @param aInner the alpha channel of the color of the inner ring
+     * @param rOuter the red channel of the color of the outer ring
+     * @param gOuter the green channel of the color of the outer ring
+     * @param bOuter the blue channel of the color of the outer ring
+     * @param aOuter the alpha channel of the color of the outer ring
+     * @param sectors the number of sectors used to approximate curvature
+     */
+    public Annulus(float centerX, float centerY, float Z,
+        float innerRadius, float outerRadius,
+        float rInner, float gInner, float bInner, float aInner,
+        float rOuter, float gOuter, float bOuter, float aOuter,
+        int sectors) {
+        super(GL10.GL_TRIANGLES, GL10.GL_UNSIGNED_SHORT,
+              false, false, true);
+
+        int radii = sectors + 1;
+
+        int[] vertices = new int[2 * 3 * radii];
+        int[] colors = new int[2 * 4 * radii];
+        short[] indices = new short[2 * 3 * radii];
+
+        int vidx = 0;
+        int cidx = 0;
+        int iidx = 0;
+
+        for (int i = 0; i < radii; i++) {
+            float theta = (i * TWO_PI) / (radii - 1);
+            float cosTheta = (float) Math.cos(theta);
+            float sinTheta = (float) Math.sin(theta);
+
+            vertices[vidx++] = toFixed(centerX + innerRadius * cosTheta);
+            vertices[vidx++] = toFixed(centerY + innerRadius * sinTheta);
+            vertices[vidx++] = toFixed(Z);
+
+            vertices[vidx++] = toFixed(centerX + outerRadius * cosTheta);
+            vertices[vidx++] = toFixed(centerY + outerRadius * sinTheta);
+            vertices[vidx++] = toFixed(Z);
+        
+            colors[cidx++] = toFixed(rInner);
+            colors[cidx++] = toFixed(gInner);
+            colors[cidx++] = toFixed(bInner);
+            colors[cidx++] = toFixed(aInner);
+
+            colors[cidx++] = toFixed(rOuter);
+            colors[cidx++] = toFixed(gOuter);
+            colors[cidx++] = toFixed(bOuter);
+            colors[cidx++] = toFixed(aOuter);
+        }
+
+        for (int i = 0; i < sectors; i++) {
+            indices[iidx++] = (short) (2 * i);
+            indices[iidx++] = (short) (2 * i + 1);
+            indices[iidx++] = (short) (2 * i + 2);
+
+            indices[iidx++] = (short) (2 * i + 1);
+            indices[iidx++] = (short) (2 * i + 3);
+            indices[iidx++] = (short) (2 * i + 2);
+        }
+        
+        allocateBuffers(vertices, null, null, colors, indices);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/City.java b/samples/GlobalTime/src/com/android/globaltime/City.java
new file mode 100644
index 0000000..0b4cb84
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/City.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * A class representing a city, with an associated position, time zone name,
+ * and raw offset from UTC.
+ */
+public  class City implements Comparable<City> {
+
+    private static Map<String,City> cities = new HashMap<String,City>();
+    private static City[] citiesByRawOffset;
+
+    private String name;
+    private String timeZoneID;
+    private TimeZone timeZone = null;
+    private int rawOffset;
+    private float latitude, longitude;
+    private float x, y, z;
+    
+    /**
+     * Loads the city database.  The cities must be stored in order by raw
+     * offset from UTC.
+     */
+    public static void loadCities(InputStream is) throws IOException {
+        DataInputStream dis = new DataInputStream(is);
+        int numCities = dis.readInt();
+        citiesByRawOffset = new City[numCities];
+
+        byte[] buf = new byte[24];
+        for (int i = 0; i < numCities; i++) {
+            String name = dis.readUTF();
+            String tzid = dis.readUTF();
+            dis.read(buf);
+  
+//          The code below is a faster version of:            
+//          int rawOffset = dis.readInt();
+//          float latitude = dis.readFloat();
+//          float longitude = dis.readFloat();
+//          float cx = dis.readFloat();
+//          float cy = dis.readFloat();
+//          float cz = dis.readFloat();
+
+            int rawOffset =
+                       (buf[ 0] << 24) |       ((buf[ 1] & 0xff) << 16) |
+                      ((buf[ 2] & 0xff) << 8) | (buf[ 3] & 0xff);
+            int ilat = (buf[ 4] << 24) |       ((buf[ 5] & 0xff) << 16) |
+                      ((buf[ 6] & 0xff) << 8) | (buf[ 7] & 0xff);
+            int ilon = (buf[ 8] << 24) |       ((buf[ 9] & 0xff) << 16) |
+                      ((buf[10] & 0xff) << 8) | (buf[11] & 0xff);
+            int icx =  (buf[12] << 24) |       ((buf[13] & 0xff) << 16) |
+                      ((buf[14] & 0xff) << 8) | (buf[15] & 0xff);
+            int icy =  (buf[16] << 24) |       ((buf[17] & 0xff) << 16) |
+                      ((buf[18] & 0xff) << 8) | (buf[19] & 0xff);
+            int icz =  (buf[20] << 24) |       ((buf[21] & 0xff) << 16) |
+                      ((buf[22] & 0xff) << 8) | (buf[23] & 0xff);
+            float latitude = Float.intBitsToFloat(ilat);
+            float longitude = Float.intBitsToFloat(ilon);
+            float cx = Float.intBitsToFloat(icx);
+            float cy = Float.intBitsToFloat(icy);
+            float cz = Float.intBitsToFloat(icz);
+
+            City city = new City(name, tzid, rawOffset,
+                                 latitude, longitude, cx, cy, cz);
+
+            cities.put(name, city);
+            citiesByRawOffset[i] = city;
+        }
+    }
+    
+    /**
+     * Returns the cities, ordered by name.
+     */
+    public static City[] getCitiesByName() {
+        City[] ocities = new City[cities.size()];
+        Iterator<City> iter = cities.values().iterator();
+        int idx = 0;
+        while (iter.hasNext()) {
+            ocities[idx++] = iter.next();
+        }
+        Arrays.sort(ocities);
+        return ocities;
+    }
+    
+    /**
+     * Returns the cities, ordered by offset, accounting for summer/daylight
+     * savings time.  This requires reading the entire time zone database
+     * behind the scenes.
+     */
+    public static City[] getCitiesByOffset() {
+        City[] ocities = new City[cities.size()];
+        Iterator<City> iter = cities.values().iterator();
+        int idx = 0;
+        while (iter.hasNext()) {
+            ocities[idx++] = iter.next();
+        }
+        Arrays.sort(ocities, new Comparator() {
+                public int compare(Object o1, Object o2) {
+                    long now = System.currentTimeMillis();
+                    City c1 = (City)o1;
+                    City c2 = (City)o2;
+                    TimeZone tz1 = c1.getTimeZone();
+                    TimeZone tz2 = c2.getTimeZone();
+                    int off1 = tz1.getOffset(now);
+                    int off2 = tz2.getOffset(now);
+                    if (off1 == off2) {
+                        float dlat = c2.getLatitude() - c1.getLatitude();
+                        if (dlat < 0.0f) return -1;
+                        if (dlat > 0.0f) return 1;
+                        return 0;
+                    }
+                    return off1 - off2;
+                }
+            });
+        return ocities;
+    }
+    
+    
+    /**
+     * Returns the cities, ordered by offset, accounting for summer/daylight
+     * savings time.  This does not require reading the time zone database
+     * since the cities are pre-sorted.
+     */
+    public static City[] getCitiesByRawOffset() {
+        return citiesByRawOffset;
+    }
+    
+    /**
+     * Returns an Iterator over all cities, in raw offset order.
+     */
+    public static Iterator<City> iterator() {
+        return cities.values().iterator();
+    }
+    
+    /**
+     * Returns the total number of cities.
+     */
+    public static int numCities() {
+        return cities.size();
+    }
+    
+    /**
+     * Constructs a city with the given name, time zone name, raw offset,
+     * latitude, longitude, and 3D (X, Y, Z) coordinate.
+     */
+    public City(String name, String timeZoneID,
+                int rawOffset,
+                float latitude, float longitude,
+                float x, float y, float z) {
+        this.name = name;
+        this.timeZoneID = timeZoneID;
+        this.rawOffset = rawOffset;
+        this.latitude = latitude;
+        this.longitude = longitude;
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public TimeZone getTimeZone() {
+        if (timeZone == null) {
+            timeZone = TimeZone.getTimeZone(timeZoneID);
+        }
+        return timeZone;
+    }
+    
+    public float getLongitude() {
+        return longitude;
+    }
+    
+    public float getLatitude() {
+        return latitude;
+    }
+    
+    public float getX() {
+        return x;
+    }
+    
+    public float getY() {
+        return y;
+    }
+    
+    public float getZ() {
+        return z;
+    }
+    
+    public float getRawOffset() {
+        return rawOffset / 3600000.0f;
+    }
+
+    public int getRawOffsetMillis() {
+        return rawOffset;
+    }
+    
+    /**
+     * Returns this city's offset from UTC, taking summer/daylight savigns
+     * time into account.
+     */
+    public float getOffset() {
+        long now = System.currentTimeMillis();
+        if (timeZone == null) {
+            timeZone = TimeZone.getTimeZone(timeZoneID);
+        }
+        return timeZone.getOffset(now) / 3600000.0f;
+    }
+    
+    /**
+     * Compares this city to another by name.
+     */
+    public int compareTo(City o) {
+        return name.compareTo(o.name);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/Clock.java b/samples/GlobalTime/src/com/android/globaltime/Clock.java
new file mode 100644
index 0000000..9aad71a
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/Clock.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.text.format.DateUtils;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+/**
+ * A class that draws an analog clock face with information about the current
+ * time in a given city.
+ */
+public class Clock {
+
+    static final int MILLISECONDS_PER_MINUTE = 60 * 1000;
+    static final int MILLISECONDS_PER_HOUR = 60 * 60 * 1000;
+
+    private City mCity = null;
+    private long mCitySwitchTime;
+    private long mTime;
+
+    private float mColorRed = 1.0f;
+    private float mColorGreen = 1.0f;
+    private float mColorBlue = 1.0f;
+
+    private long mOldOffset;
+
+    private Interpolator mClockHandInterpolator =
+        new AccelerateDecelerateInterpolator();
+
+    public Clock() {
+        // Empty constructor
+    }
+
+    /**
+     * Adds a line to the given Path.  The line extends from
+     * radius r0 to radius r1 about the center point (cx, cy),
+     * at an angle given by pos.
+     * 
+     * @param path the Path to draw to
+     * @param radius the radius of the outer rim of the clock
+     * @param pos the angle, with 0 and 1 at 12:00
+     * @param cx the X coordinate of the clock center
+     * @param cy the Y coordinate of the clock center
+     * @param r0 the starting radius for the line
+     * @param r1 the ending radius for the line
+     */
+    private static void drawLine(Path path,
+        float radius, float pos, float cx, float cy, float r0, float r1) {
+        float theta = pos * Shape.TWO_PI - Shape.PI_OVER_TWO;
+        float dx = (float) Math.cos(theta);
+        float dy = (float) Math.sin(theta);
+        float p0x = cx + dx * r0;
+        float p0y = cy + dy * r0;
+        float p1x = cx + dx * r1;
+        float p1y = cy + dy * r1;
+
+        float ox =  (p1y - p0y);
+        float oy = -(p1x - p0x);
+
+        float norm = (radius / 2.0f) / (float) Math.sqrt(ox * ox + oy * oy);
+        ox *= norm;
+        oy *= norm;
+
+        path.moveTo(p0x - ox, p0y - oy);
+        path.lineTo(p1x - ox, p1y - oy);
+        path.lineTo(p1x + ox, p1y + oy);
+        path.lineTo(p0x + ox, p0y + oy);
+        path.close();
+    }
+
+    /**
+     * Adds a vertical arrow to the given Path.
+     * 
+     * @param path the Path to draw to
+     */
+    private static void drawVArrow(Path path,
+        float cx, float cy, float width, float height) {
+        path.moveTo(cx - width / 2.0f, cy);
+        path.lineTo(cx, cy + height);
+        path.lineTo(cx + width / 2.0f, cy);
+        path.close();
+    }
+
+    /**
+     * Adds a horizontal arrow to the given Path.
+     * 
+     * @param path the Path to draw to
+     */
+    private static void drawHArrow(Path path,
+        float cx, float cy, float width, float height) {
+        path.moveTo(cx, cy - height / 2.0f);
+        path.lineTo(cx + width, cy);
+        path.lineTo(cx, cy + height / 2.0f);
+        path.close();
+    }
+
+    /**
+     * Returns an offset in milliseconds to be subtracted from the current time
+     * in order to obtain an smooth interpolation between the previously
+     * displayed time and the current time.
+     */
+    private long getOffset(float lerp) {
+        long doffset = (long) (mCity.getOffset() *
+            (float) MILLISECONDS_PER_HOUR - mOldOffset);
+        int sign;
+        if (doffset < 0) {
+            doffset = -doffset;
+            sign = -1;
+        } else {
+            sign = 1;
+        }
+
+        while (doffset > 12L * MILLISECONDS_PER_HOUR) {
+            doffset -= 12L * MILLISECONDS_PER_HOUR;
+        }
+        if (doffset > 6L * MILLISECONDS_PER_HOUR) {
+            doffset = 12L * MILLISECONDS_PER_HOUR - doffset;
+            sign = -sign;
+        }
+
+        // Interpolate doffset towards 0
+        doffset = (long)((1.0f - lerp)*doffset);
+
+        // Keep the same seconds count
+        long dh = doffset / (MILLISECONDS_PER_HOUR);
+        doffset -= dh * MILLISECONDS_PER_HOUR;
+        long dm = doffset / MILLISECONDS_PER_MINUTE;
+        doffset = sign * (60 * dh + dm) * MILLISECONDS_PER_MINUTE;
+    
+        return doffset;
+    }
+
+    /**
+     * Set the city to be displayed.  setCity(null) resets things so the clock
+     * hand animation won't occur next time.
+     */
+    public void setCity(City city) {
+        if (mCity != city) {
+            if (mCity != null) {
+                mOldOffset =
+                    (long) (mCity.getOffset() * (float) MILLISECONDS_PER_HOUR);
+            } else if (city != null) {
+                mOldOffset =
+                    (long) (city.getOffset() * (float) MILLISECONDS_PER_HOUR);
+            } else {
+                mOldOffset = 0L; // this will never be used
+            }
+            this.mCitySwitchTime = System.currentTimeMillis();
+            this.mCity = city;
+        }
+    }
+
+    public void setTime(long time) {
+        this.mTime = time;
+    }
+
+    /**
+     * Draws the clock face.
+     * 
+     * @param canvas the Canvas to draw to
+     * @param cx the X coordinate of the clock center
+     * @param cy the Y coordinate of the clock center
+     * @param radius the radius of the clock face
+     * @param alpha the translucency of the clock face
+     * @param textAlpha the translucency of the text
+     * @param showCityName if true, display the city name
+     * @param showTime if true, display the time digitally
+     * @param showUpArrow if true, display an up arrow
+     * @param showDownArrow if true, display a down arrow
+     * @param showLeftRightArrows if true, display left and right arrows
+     * @param prefixChars number of characters of the city name to draw in bold
+     */
+    public void drawClock(Canvas canvas,
+        float cx, float cy, float radius, float alpha, float textAlpha,
+        boolean showCityName, boolean showTime,
+        boolean showUpArrow,  boolean showDownArrow, boolean showLeftRightArrows,
+        int prefixChars) {
+        Paint paint = new Paint();
+        paint.setAntiAlias(true);
+
+        int iradius = (int)radius;
+
+        TimeZone tz = mCity.getTimeZone();
+
+        // Compute an interpolated time to animate between the previously
+        // displayed time and the current time
+        float lerp = Math.min(1.0f,
+            (System.currentTimeMillis() - mCitySwitchTime) / 500.0f);
+        lerp = mClockHandInterpolator.getInterpolation(lerp);
+        long doffset = lerp < 1.0f ? getOffset(lerp) : 0L;
+    
+        // Determine the interpolated time for the given time zone
+        Calendar cal = Calendar.getInstance(tz);
+        cal.setTimeInMillis(mTime - doffset);
+        int hour = cal.get(Calendar.HOUR_OF_DAY);
+        int minute = cal.get(Calendar.MINUTE);
+        int second = cal.get(Calendar.SECOND);
+        int milli = cal.get(Calendar.MILLISECOND);
+
+        float offset = tz.getRawOffset() / (float) MILLISECONDS_PER_HOUR;
+        float daylightOffset = tz.inDaylightTime(new Date(mTime)) ?
+            tz.getDSTSavings() / (float) MILLISECONDS_PER_HOUR : 0.0f;
+
+        float absOffset = offset < 0 ? -offset : offset;
+        int offsetH = (int) absOffset;
+        int offsetM = (int) (60.0f * (absOffset - offsetH));
+        hour %= 12;
+
+        // Get the city name and digital time strings
+        String cityName = mCity.getName();
+        cal.setTimeInMillis(mTime);
+        String time = DateUtils.timeString(cal.getTimeInMillis()) + " "  +
+            DateUtils.getDayOfWeekString(cal.get(Calendar.DAY_OF_WEEK),
+                    DateUtils.LENGTH_SHORT) + " " +
+            " (UTC" +
+            (offset >= 0 ? "+" : "-") +
+            offsetH +
+            (offsetM == 0 ? "" : ":" + offsetM) +
+            (daylightOffset == 0 ? "" : "+" + daylightOffset) +
+            ")";
+
+        float th = paint.getTextSize();
+        float tw;
+
+        // Set the text color
+        paint.setARGB((int) (textAlpha * 255.0f),
+                      (int) (mColorRed * 255.0f),
+                      (int) (mColorGreen * 255.0f),
+                      (int) (mColorBlue * 255.0f));
+
+        tw = paint.measureText(cityName);
+        if (showCityName) {
+            // Increment prefixChars to include any spaces
+            for (int i = 0; i < prefixChars; i++) {
+                if (cityName.charAt(i) == ' ') {
+                    ++prefixChars;
+                }
+            }
+
+            // Draw the city name
+            canvas.drawText(cityName, cx - tw / 2, cy - radius - th, paint);
+            // Overstrike the first 'prefixChars' characters
+            canvas.drawText(cityName.substring(0, prefixChars),
+                            cx - tw / 2 + 1, cy - radius - th, paint);
+        }
+        tw = paint.measureText(time);
+        if (showTime) {
+            canvas.drawText(time, cx - tw / 2, cy + radius + th + 5, paint);
+        }
+
+        paint.setARGB((int)(alpha * 255.0f),
+                      (int)(mColorRed * 255.0f),
+                      (int)(mColorGreen * 255.0f),
+                      (int)(mColorBlue * 255.0f));
+
+        paint.setStyle(Paint.Style.FILL);
+        canvas.drawOval(new RectF(cx - 2, cy - 2, cx + 2, cy + 2), paint);
+
+        paint.setStyle(Paint.Style.STROKE);
+        paint.setStrokeWidth(radius * 0.12f);
+
+        canvas.drawOval(new RectF(cx - iradius, cy - iradius,
+                                  cx + iradius, cy + iradius),
+                        paint);
+
+        float r0 = radius * 0.1f;
+        float r1 = radius * 0.4f;
+        float r2 = radius * 0.6f;
+        float r3 = radius * 0.65f;
+        float r4 = radius * 0.7f;
+        float r5 = radius * 0.9f;
+
+        Path path = new Path();
+
+        float ss = second + milli / 1000.0f;
+        float mm = minute + ss / 60.0f;
+        float hh = hour + mm / 60.0f;
+
+        // Tics for the hours
+        for (int i = 0; i < 12; i++) {
+            drawLine(path, radius * 0.12f, i / 12.0f, cx, cy, r4, r5);
+        }
+
+        // Hour hand
+        drawLine(path, radius * 0.12f, hh / 12.0f, cx, cy, r0, r1); 
+        // Minute hand
+        drawLine(path, radius * 0.12f, mm / 60.0f, cx, cy, r0, r2); 
+        // Second hand
+        drawLine(path, radius * 0.036f, ss / 60.0f, cx, cy, r0, r3); 
+
+        if (showUpArrow) {
+            drawVArrow(path, cx + radius * 1.13f, cy - radius,
+                radius * 0.15f, -radius * 0.1f);
+        }
+        if (showDownArrow) {
+            drawVArrow(path, cx + radius * 1.13f, cy + radius,
+                radius * 0.15f, radius * 0.1f);
+        }
+        if (showLeftRightArrows) {
+            drawHArrow(path, cx - radius * 1.3f, cy, -radius * 0.1f,
+                radius * 0.15f);
+            drawHArrow(path, cx + radius * 1.3f, cy,  radius * 0.1f,
+                radius * 0.15f);
+        }
+
+        paint.setStyle(Paint.Style.FILL);
+        canvas.drawPath(path, paint);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/GLView.java b/samples/GlobalTime/src/com/android/globaltime/GLView.java
new file mode 100644
index 0000000..4253717
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/GLView.java
@@ -0,0 +1,927 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.KeyEvent;
+
+class Message {
+
+    private String mText;
+    private long mExpirationTime;
+
+    public Message(String text, long expirationTime) {
+        this.mText = text;
+        this.mExpirationTime = expirationTime;
+    }
+
+    public String getText() {
+        return mText;
+    }
+
+    public long getExpirationTime() {
+        return mExpirationTime;
+    }
+}
+
+/**
+ * A helper class to simplify writing an Activity that renders using
+ * OpenGL ES.
+ *
+ * <p> A GLView object stores common elements of GL state and allows
+ * them to be modified interactively.  This is particularly useful for
+ * determining the proper settings of parameters such as the view
+ * frustum and light intensities during application development.
+ *
+ * <p> A GLView is not an actual View; instead, it is meant to be
+ * called from within a View to perform event processing on behalf of the
+ * actual View.
+ *
+ * <p> By passing key events to the GLView object from the View,
+ * the application can automatically allow certain parameters to
+ * be user-controlled from the keyboard.  Key events may be passed as
+ * shown below:
+ *
+ * <pre>
+ * GLView mGlView = new GLView();
+ *
+ * public boolean onKeyDown(int keyCode, KeyEvent event) {
+ *     // Hand the key to the GLView object first
+ *     if (mGlView.processKey(keyCode)) {
+ *         return;
+ *     }
+ *  
+ *     switch (keyCode) {
+ *     case KeyEvent.KEY_CODE_X:
+ *         // perform app processing
+ *         break;
+ *     
+ *     default:
+ *         super.onKeyDown(keyCode, event);
+ *         break;
+ *     }
+ * }
+ * </pre>
+ *
+ * <p> During drawing of a frame, the GLView object should be given the
+ * opportunity to manage GL parameters as shown below:
+ * 
+ * OpenGLContext mGLContext; // initialization not shown
+ * int mNumTrianglesDrawn = 0;
+ * 
+ * protected void onDraw(Canvas canvas) {
+ *     int w = getWidth();
+ *     int h = getHeight();
+ *         
+ *     float ratio = (float) w / h;
+ *     mGLView.setAspectRatio(ratio);
+ *
+ *     GL10 gl = (GL10) mGLContext.getGL();
+ *     mGLContext.waitNative(canvas, this);
+ *     
+ *     // Enable a light for the GLView to manipulate
+ *     gl.glEnable(GL10.GL_LIGHTING);
+ *     gl.glEnable(GL10.GL_LIGHT0);
+ *         
+ *     // Allow the GLView to set GL parameters
+ *     mGLView.setTextureParameters(gl);
+ *     mGLView.setProjection(gl);
+ *     mGLView.setView(gl);
+ *     mGLView.setLights(gl, GL10.GL_LIGHT0);
+ *         
+ *     // Draw some stuff (not shown)
+ *     mNumTrianglesDrawn += <num triangles just drawn>;
+ *     
+ *     // Wait for GL drawing to complete
+ *     mGLContext.waitGL();
+ *     
+ *     // Inform the GLView of what was drawn, and ask it to display statistics
+ *     mGLView.setNumTriangles(mNumTrianglesDrawn);
+ *     mGLView.showMessages(canvas);
+ *     mGLView.showStatistics(canvas, w);
+ * }      
+ * </pre>
+ *
+ * <p> At the end of each frame, following the call to
+ * GLContext.waitGL, the showStatistics and showMessages methods
+ * will cause additional information to be displayed.
+ *
+ * <p> To enter the interactive command mode, the 'tab' key must be
+ * pressed twice in succession.  A subsequent press of the 'tab' key
+ * exits the interactive command mode.  Entering a multi-letter code
+ * sets the parameter to be modified. The 'newline' key erases the
+ * current code, and the 'del' key deletes the last letter of
+ * the code. The parameter value may be modified by pressing the
+ * keypad left or up to decrement the value and right or down to
+ * increment the value.  The current value will be displayed as an
+ * overlay above the GL rendered content.
+ * 
+ * <p> The supported keyboard commands are as follows:
+ *
+ * <ul>
+ * <li>     h - display a list of commands
+ * <li>    fn - near frustum 
+ * <li>    ff - far frustum 
+ * <li>    tx - translate x
+ * <li>    ty - translate y
+ * <li>    tz - translate z
+ * <li>     z - zoom (frustum size)
+ * <li>    la - ambient light (all RGB channels)
+ * <li>   lar - ambient light red channel
+ * <li>   lag - ambient light green channel
+ * <li>   lab - ambient light blue channel
+ * <li>    ld - diffuse light (all RGB channels)
+ * <li>   ldr - diffuse light red channel
+ * <li>   ldg - diffuse light green channel
+ * <li>   ldb - diffuse light blue channel
+ * <li>    ls - specular light (all RGB channels)
+ * <li>   lsr - specular light red channel
+ * <li>   lsg - specular light green channel
+ * <li>   lsb - specular light blue channel
+ * <li>   lma - light model ambient (all RGB channels)
+ * <li>  lmar - light model ambient light red channel
+ * <li>  lmag - light model ambient green channel
+ * <li>  lmab - light model ambient blue channel
+ * <li>  tmin - texture min filter
+ * <li>  tmag - texture mag filter
+ * <li>  tper - texture perspective correction
+ * </ul>
+ * 
+ * {@hide}
+ */
+public class GLView {
+
+    private static final int DEFAULT_DURATION_MILLIS = 1000;
+    private static final int STATE_KEY = KeyEvent.KEYCODE_TAB;
+    private static final int HAVE_NONE = 0;
+    private static final int HAVE_ONE = 1;
+    private static final int HAVE_TWO = 2;
+
+    private static final float MESSAGE_Y_SPACING = 12.0f;
+
+    private int mState = HAVE_NONE;
+
+    private static final int NEAR_FRUSTUM  = 0;
+    private static final int FAR_FRUSTUM   = 1;
+    private static final int TRANSLATE_X   = 2;
+    private static final int TRANSLATE_Y   = 3;
+    private static final int TRANSLATE_Z   = 4;
+    private static final int ZOOM_EXPONENT = 5;
+
+    private static final int AMBIENT_INTENSITY = 6;
+    private static final int AMBIENT_RED = 7;
+    private static final int AMBIENT_GREEN = 8;
+    private static final int AMBIENT_BLUE = 9;
+
+    private static final int DIFFUSE_INTENSITY = 10;
+    private static final int DIFFUSE_RED = 11;
+    private static final int DIFFUSE_GREEN = 12;
+    private static final int DIFFUSE_BLUE = 13;
+
+    private static final int SPECULAR_INTENSITY = 14;
+    private static final int SPECULAR_RED = 15;
+    private static final int SPECULAR_GREEN = 16;
+    private static final int SPECULAR_BLUE = 17;
+
+    private static final int LIGHT_MODEL_AMBIENT_INTENSITY = 18;
+    private static final int LIGHT_MODEL_AMBIENT_RED = 19;
+    private static final int LIGHT_MODEL_AMBIENT_GREEN = 20;
+    private static final int LIGHT_MODEL_AMBIENT_BLUE = 21;
+
+    private static final int TEXTURE_MIN_FILTER = 22;
+    private static final int TEXTURE_MAG_FILTER = 23;
+    private static final int TEXTURE_PERSPECTIVE_CORRECTION = 24;
+
+    private static final String[] commands = { 
+        "fn",
+        "ff",
+        "tx",
+        "ty",
+        "tz",
+        "z",
+        "la", "lar", "lag", "lab",
+        "ld", "ldr", "ldg", "ldb",
+        "ls", "lsr", "lsg", "lsb",
+        "lma", "lmar", "lmag", "lmab",
+        "tmin", "tmag", "tper"
+   };
+
+    private static final String[] labels = {
+        "Near Frustum",
+        "Far Frustum",
+        "Translate X",
+        "Translate Y",
+        "Translate Z",
+        "Zoom",
+        "Ambient Intensity",
+        "Ambient Red",
+        "Ambient Green",
+        "Ambient Blue",
+        "Diffuse Intensity",
+        "Diffuse Red",
+        "Diffuse Green",
+        "Diffuse Blue",
+        "Specular Intenstity",
+        "Specular Red",
+        "Specular Green",
+        "Specular Blue",
+        "Light Model Ambient Intensity",
+        "Light Model Ambient Red",
+        "Light Model Ambient Green",
+        "Light Model Ambient Blue",
+        "Texture Min Filter",
+        "Texture Mag Filter",
+        "Texture Perspective Correction",
+    };
+
+    private static final float[] defaults = {
+        5.0f, 100.0f,
+        0.0f, 0.0f, -50.0f,
+        0,
+        0.125f,	1.0f, 1.0f, 1.0f,
+        0.125f,	1.0f, 1.0f, 1.0f,
+        0.125f,	1.0f, 1.0f, 1.0f,
+        0.125f,	1.0f, 1.0f, 1.0f,
+        GL10.GL_NEAREST, GL10.GL_NEAREST,
+        GL10.GL_FASTEST
+    };
+
+    private static final float[] increments = {
+        0.01f, 0.5f,
+        0.125f, 0.125f, 0.125f,
+        1.0f,
+        0.03125f, 0.1f, 0.1f, 0.1f,
+        0.03125f, 0.1f, 0.1f, 0.1f,
+        0.03125f, 0.1f, 0.1f, 0.1f,
+        0.03125f, 0.1f, 0.1f, 0.1f,
+        0, 0, 0
+    };
+
+    private float[] params = new float[commands.length];
+
+    private static final float mZoomScale = 0.109f;
+    private static final float mZoomBase  = 1.01f;
+
+    private int             mParam = -1;
+    private float           mIncr = 0;
+
+    private Paint           mPaint = new Paint();
+
+    private float           mAspectRatio = 1.0f;
+
+    private float           mZoom;
+
+    // private boolean         mPerspectiveCorrection = false;
+    // private int             mTextureMinFilter = GL10.GL_NEAREST;
+    // private int             mTextureMagFilter = GL10.GL_NEAREST;
+
+    // Counters for FPS calculation
+    private boolean         mDisplayFPS = false;
+    private boolean         mDisplayCounts = false;
+    private int             mFramesFPS = 10;
+    private long[]          mTimes = new long[mFramesFPS];
+    private int             mTimesIdx = 0;
+
+    private Map<String,Message> mMessages = new HashMap<String,Message>();
+
+    /**
+     * Constructs a new GLView.
+     */
+    public GLView() {
+        mPaint.setColor(0xffffffff);
+        reset();
+    }
+
+    /**
+     * Sets the aspect ratio (width/height) of the screen.
+     *
+     * @param aspectRatio the screen width divided by the screen height
+     */
+    public void setAspectRatio(float aspectRatio) {
+        this.mAspectRatio = aspectRatio;
+    }
+    
+    /**
+     * Sets the overall ambient light intensity.  This intensity will
+     * be used to modify the ambient light value for each of the red,
+     * green, and blue channels passed to glLightfv(...GL_AMBIENT...).
+     * The default value is 0.125f.
+     *
+     * @param intensity a floating-point value controlling the overall
+     * ambient light intensity.
+     */
+    public void setAmbientIntensity(float intensity) {
+        params[AMBIENT_INTENSITY] = intensity;
+    }
+
+    /**
+     * Sets the light model ambient intensity.  This intensity will be
+     * used to modify the ambient light value for each of the red,
+     * green, and blue channels passed to
+     * glLightModelfv(GL_LIGHT_MODEL_AMBIENT...).  The default value
+     * is 0.125f.
+     *
+     * @param intensity a floating-point value controlling the overall
+     * light model ambient intensity.
+     */
+    public void setLightModelAmbientIntensity(float intensity) {
+        params[LIGHT_MODEL_AMBIENT_INTENSITY] = intensity;
+    }
+
+    /**
+     * Sets the ambient color for the red, green, and blue channels
+     * that will be multiplied by the value of setAmbientIntensity and
+     * passed to glLightfv(...GL_AMBIENT...).  The default values are
+     * {1, 1, 1}.
+     *
+     * @param ambient an arry of three floats containing ambient
+     * red, green, and blue intensity values.
+     */
+    public void setAmbientColor(float[] ambient) {
+        params[AMBIENT_RED]   = ambient[0];
+        params[AMBIENT_GREEN] = ambient[1];
+        params[AMBIENT_BLUE]  = ambient[2];
+    }
+
+    /**
+     * Sets the overall diffuse light intensity.  This intensity will
+     * be used to modify the diffuse light value for each of the red,
+     * green, and blue channels passed to glLightfv(...GL_DIFFUSE...).
+     * The default value is 0.125f.
+     *
+     * @param intensity a floating-point value controlling the overall
+     * ambient light intensity.
+     */
+    public void setDiffuseIntensity(float intensity) {
+        params[DIFFUSE_INTENSITY] = intensity;
+    }
+
+    /**
+     * Sets the diffuse color for the red, green, and blue channels
+     * that will be multiplied by the value of setDiffuseIntensity and
+     * passed to glLightfv(...GL_DIFFUSE...).  The default values are
+     * {1, 1, 1}.
+     *
+     * @param diffuse an array of three floats containing diffuse
+     * red, green, and blue intensity values.
+     */
+    public void setDiffuseColor(float[] diffuse) {
+        params[DIFFUSE_RED]   = diffuse[0];
+        params[DIFFUSE_GREEN] = diffuse[1];
+        params[DIFFUSE_BLUE]  = diffuse[2];
+    }
+
+    /**
+     * Sets the overall specular light intensity.  This intensity will
+     * be used to modify the diffuse light value for each of the red,
+     * green, and blue channels passed to glLightfv(...GL_SPECULAR...).
+     * The default value is 0.125f.
+     *
+     * @param intensity a floating-point value controlling the overall
+     * ambient light intensity.
+     */
+    public void setSpecularIntensity(float intensity) {
+        params[SPECULAR_INTENSITY] = intensity;
+    }
+
+    /**
+     * Sets the specular color for the red, green, and blue channels
+     * that will be multiplied by the value of setSpecularIntensity and
+     * passed to glLightfv(...GL_SPECULAR...).  The default values are
+     * {1, 1, 1}.
+     *
+     * @param specular an array of three floats containing specular
+     * red, green, and blue intensity values.
+     */
+    public void setSpecularColor(float[] specular) {
+        params[SPECULAR_RED]   = specular[0];
+        params[SPECULAR_GREEN] = specular[1];
+        params[SPECULAR_BLUE]  = specular[2];
+    }
+
+    /**
+     * Returns the current X translation of the modelview
+     * transformation as passed to glTranslatef.  The default value is
+     * 0.0f.
+     *
+     * @return the X modelview translation as a float.
+     */
+    public float getTranslateX() {
+        return params[TRANSLATE_X];
+    }
+
+    /**
+     * Returns the current Y translation of the modelview
+     * transformation as passed to glTranslatef.  The default value is
+     * 0.0f.
+     *
+     * @return the Y modelview translation as a float.
+     */
+    public float getTranslateY() {
+        return params[TRANSLATE_Y];
+    }
+
+    /**
+     * Returns the current Z translation of the modelview
+     * transformation as passed to glTranslatef.  The default value is
+     * -50.0f.
+     *
+     * @return the Z modelview translation as a float.
+     */
+    public float getTranslateZ() {
+        return params[TRANSLATE_Z];
+    }
+
+    /**
+     * Sets the position of the near frustum clipping plane as passed
+     * to glFrustumf.  The default value is 5.0f;
+     *
+     * @param nearFrustum the near frustum clipping plane distance as
+     * a float.
+     */
+    public void setNearFrustum(float nearFrustum) {
+        params[NEAR_FRUSTUM] = nearFrustum;
+    }
+
+    /**
+     * Sets the position of the far frustum clipping plane as passed
+     * to glFrustumf.  The default value is 100.0f;
+     *
+     * @param farFrustum the far frustum clipping plane distance as a
+     * float.
+     */
+    public void setFarFrustum(float farFrustum) {
+        params[FAR_FRUSTUM] = farFrustum;
+    }
+
+    private void computeZoom() {
+        mZoom = mZoomScale*(float)Math.pow(mZoomBase, -params[ZOOM_EXPONENT]);
+    }
+
+    /**
+     * Resets all parameters to their default values.
+     */
+    public void reset() {
+        for (int i = 0; i < params.length; i++) {
+            params[i] = defaults[i];
+        }
+        computeZoom();
+    }
+
+    private void removeExpiredMessages() {
+        long now = System.currentTimeMillis();
+
+        List<String> toBeRemoved = new ArrayList<String>();
+
+        Iterator<String> keyIter = mMessages.keySet().iterator();
+        while (keyIter.hasNext()) {
+            String key = keyIter.next();
+            Message msg = mMessages.get(key);
+            if (msg.getExpirationTime() < now) {
+                toBeRemoved.add(key);
+            }
+        }
+
+        Iterator<String> tbrIter = toBeRemoved.iterator();
+        while (tbrIter.hasNext()) {
+            String key = tbrIter.next();
+            mMessages.remove(key);
+        }
+    }
+    
+    /**
+     * Displays the message overlay on the given Canvas.  The
+     * GLContext.waitGL method should be called prior to calling this
+     * method.  The interactive command display is drawn by this
+     * method.
+     *
+     * @param canvas the Canvas on which messages are to appear.
+     */
+    public void showMessages(Canvas canvas) {
+        removeExpiredMessages();
+
+        float y = 10.0f;
+
+        List<String> l = new ArrayList<String>();
+        l.addAll(mMessages.keySet());
+        Collections.sort(l);
+
+        Iterator<String> iter = l.iterator();
+        while (iter.hasNext()) {
+            String key = iter.next();
+            String text = mMessages.get(key).getText();
+            canvas.drawText(text, 10.0f, y, mPaint);
+            y += MESSAGE_Y_SPACING;
+        }
+    }
+
+    private int mTriangles;
+
+    /**
+     * Sets the number of triangles drawn in the previous frame for
+     * display by the showStatistics method.  The number of triangles
+     * is not computed by GLView but must be supplied by the
+     * calling Activity.
+     *
+     * @param triangles an Activity-supplied estimate of the number of 
+     * triangles drawn in the previous frame.
+     */
+    public void setNumTriangles(int triangles) {
+        this.mTriangles = triangles;
+    }
+
+    /**
+     * Displays statistics on frames and triangles per second. The
+     * GLContext.waitGL method should be called prior to calling this
+     * method.
+     *
+     * @param canvas the Canvas on which statistics are to appear.
+     * @param width the width of the Canvas.
+     */
+    public void showStatistics(Canvas canvas, int width) {	
+        long endTime = mTimes[mTimesIdx] = System.currentTimeMillis();
+        mTimesIdx = (mTimesIdx + 1) % mFramesFPS;
+
+        float th = mPaint.getTextSize();
+
+        if (mDisplayFPS) {
+            // Use end time from mFramesFPS frames ago
+            long startTime = mTimes[mTimesIdx];
+            String fps = "" + (1000.0f*mFramesFPS/(endTime - startTime));
+
+            // Normalize fps to XX.XX format
+            if (fps.indexOf(".") == 1) {
+                fps = " " + fps;
+            }
+            int len = fps.length();
+            if (len == 2) {
+                fps += ".00";
+            } else if (len == 4) {
+                fps += "0";
+            } else if (len > 5) {
+                fps = fps.substring(0, 5);
+            }
+
+            canvas.drawText(fps + " fps", width - 60.0f, 10.0f, mPaint);
+        }
+
+        if (mDisplayCounts) {
+            canvas.drawText(mTriangles + " triangles",
+                            width - 100.0f, 10.0f + th + 5, mPaint);
+        }
+    }
+
+    private void addMessage(String key, String text, int durationMillis) {
+        long expirationTime = System.currentTimeMillis() + durationMillis;
+
+        mMessages.put(key, new Message(text, expirationTime));
+    }
+
+    private void addMessage(String key, String text) {
+        addMessage(key, text, DEFAULT_DURATION_MILLIS);
+    }
+
+    private void addMessage(String text) {
+        addMessage(text, text, DEFAULT_DURATION_MILLIS);
+    }
+
+    private void clearMessages() {
+        mMessages.clear();
+    }
+
+    String command = "";
+
+    private void toggleFilter() {
+        if (params[mParam] == GL10.GL_NEAREST) {
+            params[mParam] = GL10.GL_LINEAR;
+        } else {
+            params[mParam] = GL10.GL_NEAREST;
+        }
+        addMessage(commands[mParam],
+                   "Texture " + 
+                   (mParam == TEXTURE_MIN_FILTER ? "min" : "mag") +
+                   " filter = " +
+                   (params[mParam] == GL10.GL_NEAREST ?
+                    "nearest" : "linear"));
+    }
+
+    private void togglePerspectiveCorrection() {
+        if (params[mParam] == GL10.GL_NICEST) {
+            params[mParam] = GL10.GL_FASTEST;
+        } else {
+            params[mParam] = GL10.GL_NICEST;
+        }
+        addMessage(commands[mParam],
+                   "Texture perspective correction = " +
+                   (params[mParam] == GL10.GL_FASTEST ?
+                    "fastest" : "nicest"));
+    }
+
+    private String valueString() {
+        if (mParam == TEXTURE_MIN_FILTER ||
+            mParam == TEXTURE_MAG_FILTER) {
+            if (params[mParam] == GL10.GL_NEAREST) {
+                return "nearest";
+            }
+            if (params[mParam] == GL10.GL_LINEAR) {
+                return "linear";
+            }
+        }
+        if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
+            if (params[mParam] == GL10.GL_FASTEST) {
+                return "fastest";
+            }
+            if (params[mParam] == GL10.GL_NICEST) {
+                return "nicest";
+            }
+        }
+        return "" + params[mParam];
+    }
+
+    /**
+     * 
+     * @return true if the view 
+     */
+    public boolean hasMessages() {
+        return mState == HAVE_TWO || mDisplayFPS || mDisplayCounts;
+    }
+    
+    /**
+     * Process a key stroke.  The calling Activity should pass all
+     * keys from its onKeyDown method to this method.  If the key is
+     * part of a GLView command, true is returned and the calling
+     * Activity should ignore the key event.  Otherwise, false is
+     * returned and the calling Activity may process the key event
+     * normally.
+     *
+     * @param keyCode the key code as passed to Activity.onKeyDown.
+     *
+     * @return true if the key is part of a GLView command sequence,
+     * false otherwise.
+     */
+    public boolean processKey(int keyCode) {
+        // Pressing the state key twice enters the UI
+        // Pressing it again exits the UI
+        if ((keyCode == STATE_KEY) || 
+            (keyCode == KeyEvent.KEYCODE_SLASH) || 
+            (keyCode == KeyEvent.KEYCODE_PERIOD))
+        {
+            mState = (mState + 1) % 3;
+            if (mState == HAVE_NONE) {
+                clearMessages();
+            }
+            if (mState == HAVE_TWO) {
+                clearMessages();
+                addMessage("aaaa", "GL", Integer.MAX_VALUE);
+                addMessage("aaab", "", Integer.MAX_VALUE);
+                command = "";
+            }
+            return true;
+        } else {
+            if (mState == HAVE_ONE) {
+                mState = HAVE_NONE;
+                return false;
+            }
+        }
+
+        // If we're not in the UI, exit without handling the key
+        if (mState != HAVE_TWO) {
+            return false;
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_ENTER) {
+            command = "";
+        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
+            if (command.length() > 0) {
+                command = command.substring(0, command.length() - 1);
+            }
+
+        } else if (keyCode >= KeyEvent.KEYCODE_A &&
+                   keyCode <= KeyEvent.KEYCODE_Z) {
+            command += "" + (char)(keyCode - KeyEvent.KEYCODE_A + 'a');
+        }
+
+        addMessage("aaaa", "GL " + command, Integer.MAX_VALUE);
+
+        if (command.equals("h")) {
+            addMessage("aaaa", "GL", Integer.MAX_VALUE);
+            addMessage("h - help");
+            addMessage("fn/ff - frustum near/far clip Z");
+            addMessage("la/lar/lag/lab - abmient intensity/r/g/b");
+            addMessage("ld/ldr/ldg/ldb - diffuse intensity/r/g/b");
+            addMessage("ls/lsr/lsg/lsb - specular intensity/r/g/b");
+            addMessage("s - toggle statistics display");
+            addMessage("tmin/tmag - texture min/mag filter");
+            addMessage("tpersp - texture perspective correction");
+            addMessage("tx/ty/tz - view translate x/y/z");
+            addMessage("z - zoom");
+            command = "";
+            return true;
+        } else if (command.equals("s")) {
+            mDisplayCounts = !mDisplayCounts;
+            mDisplayFPS = !mDisplayFPS;
+            command = "";
+            return true;
+        }
+
+        mParam = -1;
+        for (int i = 0; i < commands.length; i++) {
+            if (command.equals(commands[i])) {
+                mParam = i;
+                mIncr = increments[i];
+            }
+        }
+        if (mParam == -1) {
+            return true;
+        }
+
+        boolean addMessage = true;
+
+        // Increment or decrement
+        if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ||
+            keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+            if (mParam == ZOOM_EXPONENT) {
+                params[mParam] += mIncr;
+                computeZoom();
+            } else if ((mParam == TEXTURE_MIN_FILTER) ||
+                       (mParam == TEXTURE_MAG_FILTER)) {
+                toggleFilter();
+            } else if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
+                togglePerspectiveCorrection();
+            } else {
+                params[mParam] += mIncr;
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP ||
+                   keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+            if (mParam == ZOOM_EXPONENT) {
+                params[mParam] -= mIncr;
+                computeZoom();
+            } else if ((mParam == TEXTURE_MIN_FILTER) ||
+                       (mParam == TEXTURE_MAG_FILTER)) {
+                toggleFilter();
+            } else if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
+                togglePerspectiveCorrection();
+            } else {
+                params[mParam] -= mIncr;
+            }
+        }
+	
+        if (addMessage) {
+            addMessage(commands[mParam],
+                       labels[mParam] + ": " + valueString());
+        }
+
+        return true;
+    }
+
+    /**
+     * Zoom in by a given number of steps.  A negative value of steps
+     * zooms out.  Each step zooms in by 1%.
+     *
+     * @param steps the number of steps to zoom by.
+     */
+    public void zoom(int steps) {
+        params[ZOOM_EXPONENT] += steps;
+        computeZoom();
+    }
+		
+    /**
+     * Set the projection matrix using glFrustumf.  The left and right
+     * clipping planes are set at -+(aspectRatio*zoom), the bottom and
+     * top clipping planes are set at -+zoom, and the near and far
+     * clipping planes are set to the values set by setNearFrustum and
+     * setFarFrustum or interactively.
+     *
+     * <p> GL side effects:
+     * <ul>
+     *    <li>overwrites the matrix mode</li>
+     *    <li>overwrites the projection matrix</li>
+     * </ul>
+     *
+     * @param gl a GL10 instance whose projection matrix is to be modified.
+     */
+    public void setProjection(GL10 gl) {
+        gl.glMatrixMode(GL10.GL_PROJECTION);
+        gl.glLoadIdentity();
+
+        if (mAspectRatio >= 1.0f) {
+            gl.glFrustumf(-mAspectRatio*mZoom, mAspectRatio*mZoom,
+                          -mZoom, mZoom,
+                          params[NEAR_FRUSTUM], params[FAR_FRUSTUM]);
+        } else {
+            gl.glFrustumf(-mZoom, mZoom,
+                          -mZoom / mAspectRatio, mZoom / mAspectRatio,
+                          params[NEAR_FRUSTUM], params[FAR_FRUSTUM]);
+        }
+    }
+
+    /**
+     * Set the modelview matrix using glLoadIdentity and glTranslatef.
+     * The translation values are set interactively.
+     *
+     * <p> GL side effects:
+     * <ul>
+     * <li>overwrites the matrix mode</li>
+     * <li>overwrites the modelview matrix</li>
+     * </ul>
+     *
+     * @param gl a GL10 instance whose modelview matrix is to be modified.
+     */
+    public void setView(GL10 gl) {
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+
+        // Move the viewpoint backwards
+        gl.glTranslatef(params[TRANSLATE_X],
+                        params[TRANSLATE_Y],
+                        params[TRANSLATE_Z]);
+    }
+
+    /**
+     * Sets texture parameters.
+     *
+     * <p> GL side effects:
+     * <ul>
+     * <li>sets the GL_PERSPECTIVE_CORRECTION_HINT</li>
+     * <li>sets the GL_TEXTURE_MIN_FILTER texture parameter</li>
+     * <li>sets the GL_TEXTURE_MAX_FILTER texture parameter</li>
+     * </ul>
+     *
+     * @param gl a GL10 instance whose texture parameters are to be modified.
+     */
+    public void setTextureParameters(GL10 gl) {
+        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                  (int)params[TEXTURE_PERSPECTIVE_CORRECTION]);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
+                           GL10.GL_TEXTURE_MIN_FILTER,
+                           params[TEXTURE_MIN_FILTER]);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
+                           GL10.GL_TEXTURE_MAG_FILTER,
+                           params[TEXTURE_MAG_FILTER]);
+    }
+
+    /**
+     * Sets the lighting parameters for the given light.
+     *
+     * <p> GL side effects:
+     * <ul>
+     * <li>sets the GL_LIGHT_MODEL_AMBIENT intensities
+     * <li>sets the GL_AMBIENT intensities for the given light</li>
+     * <li>sets the GL_DIFFUSE intensities for the given light</li>
+     * <li>sets the GL_SPECULAR intensities for the given light</li>
+     * </ul>
+     *
+     * @param gl a GL10 instance whose texture parameters are to be modified.
+     */
+    public void setLights(GL10 gl, int lightNum) {
+        float[] light = new float[4];
+        light[3] = 1.0f;
+
+        float lmi = params[LIGHT_MODEL_AMBIENT_INTENSITY];
+        light[0] = params[LIGHT_MODEL_AMBIENT_RED]*lmi;
+        light[1] = params[LIGHT_MODEL_AMBIENT_GREEN]*lmi;
+        light[2] = params[LIGHT_MODEL_AMBIENT_BLUE]*lmi;
+        gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, light, 0);
+	
+        float ai = params[AMBIENT_INTENSITY];
+        light[0] = params[AMBIENT_RED]*ai;
+        light[1] = params[AMBIENT_GREEN]*ai;
+        light[2] = params[AMBIENT_BLUE]*ai;
+        gl.glLightfv(lightNum, GL10.GL_AMBIENT, light, 0);
+
+        float di = params[DIFFUSE_INTENSITY];
+        light[0] = params[DIFFUSE_RED]*di;
+        light[1] = params[DIFFUSE_GREEN]*di;
+        light[2] = params[DIFFUSE_BLUE]*di;
+        gl.glLightfv(lightNum, GL10.GL_DIFFUSE, light, 0);
+
+        float si = params[SPECULAR_INTENSITY];
+        light[0] = params[SPECULAR_RED]*si;
+        light[1] = params[SPECULAR_GREEN]*si;
+        light[2] = params[SPECULAR_BLUE]*si;
+        gl.glLightfv(lightNum, GL10.GL_SPECULAR, light, 0);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java b/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
new file mode 100644
index 0000000..d96b644
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
@@ -0,0 +1,1488 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.microedition.khronos.egl.*;
+import javax.microedition.khronos.opengles.*;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.graphics.Canvas;
+import android.opengl.Object3D;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+/**
+ * The main View of the GlobalTime Activity.
+ */
+class GTView extends SurfaceView implements SurfaceHolder.Callback {
+
+    /**
+     * A TimeZone object used to compute the current UTC time.
+     */
+    private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("utc");
+
+    /**
+     * The Sun's color is close to that of a 5780K blackbody.
+     */
+    private static final float[] SUNLIGHT_COLOR = {
+        1.0f, 0.9375f, 0.91015625f, 1.0f
+    };
+
+    /**
+     * The inclination of the earth relative to the plane of the ecliptic
+     * is 23.45 degrees.
+     */
+    private static final float EARTH_INCLINATION = 23.45f * Shape.PI / 180.0f;
+
+    /** Seconds in a day */
+    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
+
+    /** Flag for the depth test */
+    private static final boolean PERFORM_DEPTH_TEST= false;
+
+    /** Use raw time zone offsets, disregarding "summer time."  If false,
+     * current offsets will be used, which requires a much longer startup time
+     * in order to sort the city database.
+     */
+    private static final boolean USE_RAW_OFFSETS = true;
+
+    /**
+     * The earth's atmosphere.
+     */
+    private static final Annulus ATMOSPHERE =
+        new Annulus(0.0f, 0.0f, 1.75f, 0.9f, 1.08f, 0.4f, 0.4f, 0.8f, 0.0f,
+            0.0f, 0.0f, 0.0f, 1.0f, 50);
+
+    /**
+     * The tesselation of the earth by latitude.
+     */
+    private static final int SPHERE_LATITUDES = 25;
+
+    /**
+     * The tesselation of the earth by longitude.
+     */
+    private static int SPHERE_LONGITUDES = 25;
+
+    /**
+     * A flattened version of the earth.  The normals are computed identically
+     * to those of the round earth, allowing the day/night lighting to be
+     * applied to the flattened surface.
+     */
+    private static Sphere worldFlat = new LatLongSphere(0.0f, 0.0f, 0.0f, 1.0f,
+        SPHERE_LATITUDES, SPHERE_LONGITUDES,
+        0.0f, 360.0f, true, true, false, true);
+
+    /**
+     * The earth.
+     */
+    private Object3D mWorld;
+
+    /**
+     * Geometry of the city lights
+     */
+    private PointCloud mLights;
+
+    /**
+     * True if the activiy has been initialized.
+     */
+    boolean mInitialized = false;
+
+    /**
+     * True if we're in alphabetic entry mode.
+     */
+    private boolean mAlphaKeySet = false;
+
+    private EGLContext mEGLContext;
+    private EGLSurface mEGLSurface;
+    private EGLDisplay mEGLDisplay;
+    private EGLConfig  mEGLConfig;
+    GLView  mGLView;
+
+    // Rotation and tilt of the Earth
+    private float mRotAngle = 0.0f;
+    private float mTiltAngle = 0.0f;
+
+    // Rotational velocity of the orbiting viewer
+    private float mRotVelocity = 1.0f;
+
+    // Rotation of the flat view
+    private float mWrapX =  0.0f;
+    private float  mWrapVelocity =  0.0f;
+    private float mWrapVelocityFactor =  0.01f;
+
+    // Toggle switches
+    private boolean mDisplayAtmosphere = true;
+    private boolean mDisplayClock = false;
+    private boolean mClockShowing = false;
+    private boolean mDisplayLights = false;
+    private boolean mDisplayWorld = true;
+    private boolean mDisplayWorldFlat = false;
+    private boolean mSmoothShading = true;
+
+    // City search string
+    private String mCityName = "";
+
+    // List of all cities
+    private List<City> mClockCities;
+
+    // List of cities matching a user-supplied prefix
+    private List<City> mCityNameMatches = new ArrayList<City>();
+
+    private List<City> mCities;
+
+    // Start time for clock fade animation
+    private long mClockFadeTime;
+
+    // Interpolator for clock fade animation
+    private Interpolator mClockSizeInterpolator =
+        new DecelerateInterpolator(1.0f);
+
+    // Index of current clock
+    private int mCityIndex;
+
+    // Current clock
+    private Clock mClock;
+
+    // City-to-city flight animation parameters
+    private boolean mFlyToCity = false;
+    private long mCityFlyStartTime;
+    private float mCityFlightTime;
+    private float mRotAngleStart, mRotAngleDest;
+    private float mTiltAngleStart, mTiltAngleDest;
+
+    // Interpolator for flight motion animation
+    private Interpolator mFlyToCityInterpolator =
+        new AccelerateDecelerateInterpolator();
+
+    private static int sNumLights;
+    private static int[] sLightCoords;
+
+    //     static Map<Float,int[]> cityCoords = new HashMap<Float,int[]>();
+
+    // Arrays for GL calls
+    private float[] mClipPlaneEquation = new float[4];
+    private float[] mLightDir = new float[4];
+
+    // Calendar for computing the Sun's position
+    Calendar mSunCal = Calendar.getInstance(UTC_TIME_ZONE);
+
+    // Triangles drawn per frame
+    private int mNumTriangles;
+
+    private long startTime;
+
+    private static final int MOTION_NONE = 0;
+    private static final int MOTION_X = 1;
+    private static final int MOTION_Y = 2;
+
+    private static final int MIN_MANHATTAN_DISTANCE = 20;
+    private static final float ROTATION_FACTOR = 1.0f / 30.0f;
+    private static final float TILT_FACTOR = 0.35f;
+
+    // Touchscreen support
+    private float mMotionStartX;
+    private float mMotionStartY;
+    private float mMotionStartRotVelocity;
+    private float mMotionStartTiltAngle;
+    private int mMotionDirection;
+    
+    private boolean mPaused = true;
+    private boolean mHaveSurface = false;
+    private boolean mStartAnimating = false;
+    
+    public void surfaceCreated(SurfaceHolder holder) {
+        mHaveSurface = true;
+        startEGL();
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        mHaveSurface = false;
+        stopEGL();
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        // nothing to do
+    }
+
+    /**
+     * Set up the view.
+     *
+     * @param context the Context
+     * @param am an AssetManager to retrieve the city database from
+     */
+    public GTView(Context context) {
+        super(context);
+
+        getHolder().addCallback(this);
+        getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
+
+        startTime = System.currentTimeMillis();
+
+        mClock = new Clock();
+
+        startEGL();
+        
+        setFocusable(true);
+        setFocusableInTouchMode(true);
+        requestFocus();
+    }
+
+    /**
+     * Creates an egl context. If the state of the activity is right, also
+     * creates the egl surface. Otherwise the surface will be created in a
+     * future call to createEGLSurface().
+     */
+    private void startEGL() {
+        EGL10 egl = (EGL10)EGLContext.getEGL();
+
+        if (mEGLContext == null) {
+            EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+            int[] version = new int[2];
+            egl.eglInitialize(dpy, version);
+            int[] configSpec = {
+                    EGL10.EGL_DEPTH_SIZE,   16,
+                    EGL10.EGL_NONE
+            };
+            EGLConfig[] configs = new EGLConfig[1];
+            int[] num_config = new int[1];
+            egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
+            mEGLConfig = configs[0];
+
+            mEGLContext = egl.eglCreateContext(dpy, mEGLConfig, 
+                    EGL10.EGL_NO_CONTEXT, null);
+            mEGLDisplay = dpy;
+            
+            AssetManager am = mContext.getAssets();
+            try {
+                loadAssets(am);
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+                throw new RuntimeException(ioe);
+            } catch (ArrayIndexOutOfBoundsException aioobe) {
+                aioobe.printStackTrace();
+                throw new RuntimeException(aioobe);
+            }
+        }
+        
+        if (mEGLSurface == null && !mPaused && mHaveSurface) {
+            mEGLSurface = egl.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, 
+                    this, null);
+            egl.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, 
+                    mEGLContext);
+            mInitialized = false;
+            if (mStartAnimating) {
+                startAnimating();
+                mStartAnimating = false;
+            }
+        }
+    }
+    
+    /**
+     * Destroys the egl context. If an egl surface has been created, it is
+     * destroyed as well.
+     */
+    private void stopEGL() {
+        EGL10 egl = (EGL10)EGLContext.getEGL();
+        if (mEGLSurface != null) {
+            egl.eglMakeCurrent(mEGLDisplay, 
+                    egl.EGL_NO_SURFACE, egl.EGL_NO_SURFACE, egl.EGL_NO_CONTEXT);
+            egl.eglDestroySurface(mEGLDisplay, mEGLSurface);
+            mEGLSurface = null;
+        }
+
+        if (mEGLContext != null) {
+            egl.eglDestroyContext(mEGLDisplay, mEGLContext);
+            egl.eglTerminate(mEGLDisplay);
+            mEGLContext = null;
+            mEGLDisplay = null;
+            mEGLConfig = null;
+        }
+    }
+    
+    public void onPause() {
+        mPaused = true;
+        stopAnimating();
+        stopEGL();
+    }
+    
+    public void onResume() {
+        mPaused = false;
+        startEGL();
+    }
+    
+    public void destroy() {
+        stopAnimating();
+        stopEGL();
+    }
+
+    /**
+     * Begin animation.
+     */
+    public void startAnimating() {
+        if (mEGLSurface == null) {
+            mStartAnimating = true; // will start when egl surface is created
+        } else {
+            mHandler.sendEmptyMessage(INVALIDATE);
+        }
+    }
+
+    /**
+     * Quit animation.
+     */
+    public void stopAnimating() {
+        mHandler.removeMessages(INVALIDATE);
+    }
+
+    /**
+     * Read a two-byte integer from the input stream.
+     */
+    private int readInt16(InputStream is) throws IOException {
+        int lo = is.read();
+        int hi = is.read();
+        return (hi << 8) | lo;
+    }
+
+    /**
+     * Returns the offset from UTC for the given city.  If USE_RAW_OFFSETS
+     * is true, summer/daylight savings is ignored.
+     */
+    private static float getOffset(City c) {
+        return USE_RAW_OFFSETS ? c.getRawOffset() : c.getOffset();
+    }
+
+    private InputStream cache(InputStream is) throws IOException {
+        int nbytes = is.available();
+        byte[] data = new byte[nbytes];
+        int nread = 0;
+        while (nread < nbytes) {
+            nread += is.read(data, nread, nbytes - nread);
+        }
+        return new ByteArrayInputStream(data);
+    }
+
+    /**
+     * Load the city and lights databases.
+     *
+     * @param am the AssetManager to load from.
+     */
+    private void loadAssets(final AssetManager am) throws IOException {
+        Locale locale = Locale.getDefault();
+        String language = locale.getLanguage();
+        String country = locale.getCountry();
+
+        InputStream cis = null;
+        try {
+            // Look for (e.g.) cities_fr_FR.dat or cities_fr_CA.dat
+            cis = am.open("cities_" + language + "_" + country + ".dat");
+        } catch (FileNotFoundException e1) {
+            try {
+                // Look for (e.g.) cities_fr.dat or cities_fr.dat
+                cis = am.open("cities_" + language + ".dat");
+            } catch (FileNotFoundException e2) {
+                try {
+                    // Use English city names by default
+                    cis = am.open("cities_en.dat");
+                } catch (FileNotFoundException e3) {
+                    throw e3;
+                }
+            }
+        }
+
+        cis = cache(cis);
+        City.loadCities(cis);
+        City[] cities;
+        if (USE_RAW_OFFSETS) {
+            cities = City.getCitiesByRawOffset();
+        } else {
+            cities = City.getCitiesByOffset();
+        }
+
+        mClockCities = new ArrayList<City>(cities.length);
+        for (int i = 0; i < cities.length; i++) {
+            mClockCities.add(cities[i]);
+        }
+        mCities = mClockCities;
+        mCityIndex = 0;
+
+        this.mWorld = new Object3D() {
+                @Override
+                public InputStream readFile(String filename)
+                    throws IOException {
+                    return cache(am.open(filename));
+                }
+            };
+
+        mWorld.load("world.gles");
+
+        // lights.dat has the following format.  All integers
+        // are 16 bits, low byte first.
+        //
+        // width
+        // height
+        // N [# of lights]
+        // light 0 X [in the range 0 to (width - 1)]
+        // light 0 Y ]in the range 0 to (height - 1)]
+        // light 1 X [in the range 0 to (width - 1)]
+        // light 1 Y ]in the range 0 to (height - 1)]
+        // ...
+        // light (N - 1) X [in the range 0 to (width - 1)]
+        // light (N - 1) Y ]in the range 0 to (height - 1)]
+        //
+        // For a larger number of lights, it could make more
+        // sense to store the light positions in a bitmap
+        // and extract them manually
+        InputStream lis = am.open("lights.dat");
+        lis = cache(lis);
+
+        int lightWidth = readInt16(lis);
+        int lightHeight = readInt16(lis);
+        sNumLights = readInt16(lis);
+        sLightCoords = new int[3 * sNumLights];
+
+        int lidx = 0;
+        float lightRadius = 1.009f;
+        float lightScale = 65536.0f * lightRadius;
+
+        float[] cosTheta = new float[lightWidth];
+        float[] sinTheta = new float[lightWidth];
+        float twoPi = (float) (2.0 * Math.PI);
+        float scaleW = twoPi / lightWidth;
+        for (int i = 0; i < lightWidth; i++) {
+            float theta = twoPi - i * scaleW;
+            cosTheta[i] = (float)Math.cos(theta);
+            sinTheta[i] = (float)Math.sin(theta);
+        }
+
+        float[] cosPhi = new float[lightHeight];
+        float[] sinPhi = new float[lightHeight];
+        float scaleH = (float) (Math.PI / lightHeight);
+        for (int j = 0; j < lightHeight; j++) {
+            float phi = j * scaleH;
+            cosPhi[j] = (float)Math.cos(phi);
+            sinPhi[j] = (float)Math.sin(phi);
+        }
+
+        int nbytes = 4 * sNumLights;
+        byte[] ilights = new byte[nbytes];
+        int nread = 0;
+        while (nread < nbytes) {
+            nread += lis.read(ilights, nread, nbytes - nread);
+        }
+
+        int idx = 0;
+        for (int i = 0; i < sNumLights; i++) {
+            int lx = (((ilights[idx + 1] & 0xff) << 8) |
+                       (ilights[idx    ] & 0xff));
+            int ly = (((ilights[idx + 3] & 0xff) << 8) |
+                       (ilights[idx + 2] & 0xff));
+            idx += 4;
+
+            float sin = sinPhi[ly];
+            float x = cosTheta[lx]*sin;
+            float y = cosPhi[ly];
+            float z = sinTheta[lx]*sin;
+
+            sLightCoords[lidx++] = (int) (x * lightScale);
+            sLightCoords[lidx++] = (int) (y * lightScale);
+            sLightCoords[lidx++] = (int) (z * lightScale);
+        }
+        mLights = new PointCloud(sLightCoords);
+    }
+
+    /**
+     * Returns true if two time zone offsets are equal.  We assume distinct
+     * time zone offsets will differ by at least a few minutes.
+     */
+    private boolean tzEqual(float o1, float o2) {
+        return Math.abs(o1 - o2) < 0.001;
+    }
+
+    /**
+     * Move to a different time zone.
+     *
+     * @param incr The increment between the current and future time zones.
+     */
+    private void shiftTimeZone(int incr) {
+        // If only 1 city in the current set, there's nowhere to go
+        if (mCities.size() <= 1) {
+            return;
+        }
+
+        float offset = getOffset(mCities.get(mCityIndex));
+        do {
+            mCityIndex = (mCityIndex + mCities.size() + incr) % mCities.size();
+        } while (tzEqual(getOffset(mCities.get(mCityIndex)), offset));
+
+        offset = getOffset(mCities.get(mCityIndex));
+        locateCity(true, offset);
+        goToCity();
+    }
+
+    /**
+     * Returns true if there is another city within the current time zone
+     * that is the given increment away from the current city.
+     *
+     * @param incr the increment, +1 or -1
+     * @return
+     */
+    private boolean atEndOfTimeZone(int incr) {
+        if (mCities.size() <= 1) {
+            return true;
+        }
+
+        float offset = getOffset(mCities.get(mCityIndex));
+        int nindex = (mCityIndex + mCities.size() + incr) % mCities.size();
+        if (tzEqual(getOffset(mCities.get(nindex)), offset)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Shifts cities within the current time zone.
+     *
+     * @param incr the increment, +1 or -1
+     */
+    private void shiftWithinTimeZone(int incr) {
+        float offset = getOffset(mCities.get(mCityIndex));
+        int nindex = (mCityIndex + mCities.size() + incr) % mCities.size();
+        if (tzEqual(getOffset(mCities.get(nindex)), offset)) {
+            mCityIndex = nindex;
+            goToCity();
+        }
+    }
+
+    /**
+     * Returns true if the city name matches the given prefix, ignoring spaces.
+     */
+    private boolean nameMatches(City city, String prefix) {
+        String cityName = city.getName().replaceAll("[ ]", "");
+        return prefix.regionMatches(true, 0,
+                                    cityName, 0,
+                                    prefix.length());
+    }
+
+    /**
+     * Returns true if there are cities matching the given name prefix.
+     */
+    private boolean hasMatches(String prefix) {
+        for (int i = 0; i < mClockCities.size(); i++) {
+            City city = mClockCities.get(i);
+            if (nameMatches(city, prefix)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Shifts to the nearest city that matches the new prefix.
+     */
+    private void shiftByName() {
+        // Attempt to keep current city if it matches
+        City finalCity = null;
+        City currCity = mCities.get(mCityIndex);
+        if (nameMatches(currCity, mCityName)) {
+            finalCity = currCity;
+        }
+
+        mCityNameMatches.clear();
+        for (int i = 0; i < mClockCities.size(); i++) {
+            City city = mClockCities.get(i);
+            if (nameMatches(city, mCityName)) {
+                mCityNameMatches.add(city);
+            }
+        }
+
+        mCities = mCityNameMatches;
+
+        if (finalCity != null) {
+            for (int i = 0; i < mCityNameMatches.size(); i++) {
+                if (mCityNameMatches.get(i) == finalCity) {
+                    mCityIndex = i;
+                    break;
+                }
+            }
+        } else {
+            // Find the closest matching city
+            locateCity(false, 0.0f);
+        }
+        goToCity();
+    }
+
+    /**
+     * Increases or decreases the rotational speed of the earth.
+     */
+    private void incrementRotationalVelocity(float incr) {
+        if (mDisplayWorldFlat) {
+            mWrapVelocity -= incr;
+        } else {
+            mRotVelocity -= incr;
+        }
+    }
+
+    /**
+     * Clears the current matching prefix, while keeping the focus on
+     * the current city.
+     */
+    private void clearCityMatches() {
+        // Determine the global city index that matches the current city
+        if (mCityNameMatches.size() > 0) {
+            City city = mCityNameMatches.get(mCityIndex);
+            for (int i = 0; i < mClockCities.size(); i++) {
+                City ncity = mClockCities.get(i);
+                if (city.equals(ncity)) {
+                    mCityIndex = i;
+                    break;
+                }
+            }
+        }
+
+        mCityName = "";
+        mCityNameMatches.clear();
+        mCities = mClockCities;
+        goToCity();
+    }
+
+    /**
+     * Fade the clock in or out.
+     */
+    private void enableClock(boolean enabled) {
+        mClockFadeTime = System.currentTimeMillis();
+        mDisplayClock = enabled;
+        mClockShowing = true;
+        mAlphaKeySet = enabled;
+        if (enabled) {
+            // Find the closest matching city
+            locateCity(false, 0.0f);
+        }
+        clearCityMatches();
+    }
+
+    /**
+     * Use the touchscreen to alter the rotational velocity or the
+     * tilt of the earth.
+     */
+    @Override public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mMotionStartX = event.getX();
+                mMotionStartY = event.getY();
+                mMotionStartRotVelocity = mDisplayWorldFlat ?
+                    mWrapVelocity : mRotVelocity;
+                mMotionStartTiltAngle = mTiltAngle;
+
+                // Stop the rotation
+                if (mDisplayWorldFlat) {
+                    mWrapVelocity = 0.0f;
+                } else {
+                    mRotVelocity = 0.0f;
+                }
+                mMotionDirection = MOTION_NONE;
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                // Disregard motion events when the clock is displayed
+                float dx = event.getX() - mMotionStartX;
+                float dy = event.getY() - mMotionStartY;
+                float delx = Math.abs(dx);
+                float dely = Math.abs(dy);
+
+                // Determine the direction of motion (major axis)
+                // Once if has been determined, it's locked in until
+                // we receive ACTION_UP or ACTION_CANCEL
+                if ((mMotionDirection == MOTION_NONE) &&
+                    (delx + dely > MIN_MANHATTAN_DISTANCE)) {
+                    if (delx > dely) {
+                        mMotionDirection = MOTION_X;
+                    } else {
+                        mMotionDirection = MOTION_Y;
+                    }
+                }
+
+                // If the clock is displayed, don't actually rotate or tilt;
+                // just use mMotionDirection to record whether motion occurred
+                if (!mDisplayClock) {
+                    if (mMotionDirection == MOTION_X) {
+                        if (mDisplayWorldFlat) {
+                            mWrapVelocity = mMotionStartRotVelocity +
+                                dx * ROTATION_FACTOR;
+                        } else {
+                            mRotVelocity = mMotionStartRotVelocity +
+                                dx * ROTATION_FACTOR;
+                        }
+                        mClock.setCity(null);
+                    } else if (mMotionDirection == MOTION_Y &&
+                        !mDisplayWorldFlat) {
+                        mTiltAngle = mMotionStartTiltAngle + dy * TILT_FACTOR;
+                        if (mTiltAngle < -90.0f) {
+                            mTiltAngle = -90.0f;
+                        }
+                        if (mTiltAngle > 90.0f) {
+                            mTiltAngle = 90.0f;
+                        }
+                        mClock.setCity(null);
+                    }
+                }
+                break;
+
+            case MotionEvent.ACTION_UP:
+                mMotionDirection = MOTION_NONE;
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+                mTiltAngle = mMotionStartTiltAngle;
+                if (mDisplayWorldFlat) {
+                    mWrapVelocity = mMotionStartRotVelocity;
+                } else {
+                    mRotVelocity = mMotionStartRotVelocity;
+                }
+                mMotionDirection = MOTION_NONE;
+                break;
+        }
+        return true;
+    }
+
+    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (mInitialized && mGLView.processKey(keyCode)) {
+            boolean drawing = (mClockShowing || mGLView.hasMessages());
+            this.setWillNotDraw(!drawing);
+            return true;
+        }
+
+        boolean handled = false;
+
+        // If we're not in alphabetical entry mode, convert letters
+        // to their digit equivalents
+        if (!mAlphaKeySet) {
+            char numChar = event.getNumber();
+            if (numChar >= '0' && numChar <= '9') {
+                keyCode = KeyEvent.KEYCODE_0 + (numChar - '0');
+            }
+        }
+
+        switch (keyCode) {
+        // The 'space' key toggles the clock
+        case KeyEvent.KEYCODE_SPACE:
+            mAlphaKeySet = !mAlphaKeySet;
+            enableClock(mAlphaKeySet);
+            handled = true;
+            break;
+
+        // The 'left' and 'right' buttons shift time zones if the clock is
+        // displayed, otherwise they alters the rotational speed of the earthh
+        case KeyEvent.KEYCODE_DPAD_LEFT:
+            if (mDisplayClock) {
+                shiftTimeZone(-1);
+            } else {
+                mClock.setCity(null);
+                incrementRotationalVelocity(1.0f);
+            }
+            handled = true;
+            break;
+
+        case KeyEvent.KEYCODE_DPAD_RIGHT:
+            if (mDisplayClock) {
+                shiftTimeZone(1);
+            } else {
+                mClock.setCity(null);
+                incrementRotationalVelocity(-1.0f);
+            }
+            handled = true;
+            break;
+
+        // The 'up' and 'down' buttons shift cities within a time zone if the
+        // clock is displayed, otherwise they tilt the earth
+        case KeyEvent.KEYCODE_DPAD_UP:
+            if (mDisplayClock) {
+                shiftWithinTimeZone(-1);
+            } else {
+                mClock.setCity(null);
+                if (!mDisplayWorldFlat) {
+                    mTiltAngle += 360.0f / 48.0f;
+                }
+            }
+            handled = true;
+            break;
+
+        case KeyEvent.KEYCODE_DPAD_DOWN:
+            if (mDisplayClock) {
+                shiftWithinTimeZone(1);
+            } else {
+                mClock.setCity(null);
+                if (!mDisplayWorldFlat) {
+                    mTiltAngle -= 360.0f / 48.0f;
+                }
+            }
+            handled = true;
+            break;
+
+        // The center key stops the earth's rotation, then toggles between the
+        // round and flat views of the earth
+        case KeyEvent.KEYCODE_DPAD_CENTER:
+            if ((!mDisplayWorldFlat && mRotVelocity == 0.0f) ||
+                (mDisplayWorldFlat && mWrapVelocity == 0.0f)) {
+                mDisplayWorldFlat = !mDisplayWorldFlat;
+            } else {
+                if (mDisplayWorldFlat) {
+                    mWrapVelocity = 0.0f;
+                } else {
+                    mRotVelocity = 0.0f;
+                }
+            }
+            handled = true;
+            break;
+
+        // The 'L' key toggles the city lights
+        case KeyEvent.KEYCODE_L:
+            if (!mAlphaKeySet && !mDisplayWorldFlat) {
+                mDisplayLights = !mDisplayLights;
+                handled = true;
+            }
+            break;
+
+
+        // The 'W' key toggles the earth (just for fun)
+        case KeyEvent.KEYCODE_W:
+            if (!mAlphaKeySet && !mDisplayWorldFlat) {
+                mDisplayWorld = !mDisplayWorld;
+                handled = true;
+            }
+            break;
+
+        // The 'A' key toggles the atmosphere
+        case KeyEvent.KEYCODE_A:
+            if (!mAlphaKeySet && !mDisplayWorldFlat) {
+                mDisplayAtmosphere = !mDisplayAtmosphere;
+                handled = true;
+            }
+            break;
+
+        // The '2' key zooms out
+        case KeyEvent.KEYCODE_2:
+            if (!mAlphaKeySet && !mDisplayWorldFlat) {
+                mGLView.zoom(-2);
+                handled = true;
+            }
+            break;
+
+        // The '8' key zooms in
+        case KeyEvent.KEYCODE_8:
+            if (!mAlphaKeySet && !mDisplayWorldFlat) {
+                mGLView.zoom(2);
+                handled = true;
+            }
+            break;
+        }
+
+        // Handle letters in city names
+        if (!handled && mAlphaKeySet) {
+            switch (keyCode) {
+            // Add a letter to the city name prefix
+            case KeyEvent.KEYCODE_A:
+            case KeyEvent.KEYCODE_B:
+            case KeyEvent.KEYCODE_C:
+            case KeyEvent.KEYCODE_D:
+            case KeyEvent.KEYCODE_E:
+            case KeyEvent.KEYCODE_F:
+            case KeyEvent.KEYCODE_G:
+            case KeyEvent.KEYCODE_H:
+            case KeyEvent.KEYCODE_I:
+            case KeyEvent.KEYCODE_J:
+            case KeyEvent.KEYCODE_K:
+            case KeyEvent.KEYCODE_L:
+            case KeyEvent.KEYCODE_M:
+            case KeyEvent.KEYCODE_N:
+            case KeyEvent.KEYCODE_O:
+            case KeyEvent.KEYCODE_P:
+            case KeyEvent.KEYCODE_Q:
+            case KeyEvent.KEYCODE_R:
+            case KeyEvent.KEYCODE_S:
+            case KeyEvent.KEYCODE_T:
+            case KeyEvent.KEYCODE_U:
+            case KeyEvent.KEYCODE_V:
+            case KeyEvent.KEYCODE_W:
+            case KeyEvent.KEYCODE_X:
+            case KeyEvent.KEYCODE_Y:
+            case KeyEvent.KEYCODE_Z:
+                char c = (char)(keyCode - KeyEvent.KEYCODE_A + 'A');
+                if (hasMatches(mCityName + c)) {
+                    mCityName += c;
+                    shiftByName();
+                }
+                handled = true;
+                break;
+
+            // Remove a letter from the city name prefix
+            case KeyEvent.KEYCODE_DEL:
+                if (mCityName.length() > 0) {
+                    mCityName = mCityName.substring(0, mCityName.length() - 1);
+                    shiftByName();
+                } else {
+                    clearCityMatches();
+                }
+                handled = true;
+                break;
+
+            // Clear the city name prefix
+            case KeyEvent.KEYCODE_ENTER:
+                clearCityMatches();
+                handled = true;
+                break;
+            }
+        }
+
+        boolean drawing = (mClockShowing ||
+            ((mGLView != null) && (mGLView.hasMessages())));
+        this.setWillNotDraw(!drawing);
+
+        // Let the system handle other keypresses
+        if (!handled) {
+            return super.onKeyDown(keyCode, event);
+        }
+        return true;
+    }
+
+    /**
+     * Initialize OpenGL ES drawing.
+     */
+    private synchronized void init(GL10 gl) {
+        mGLView = new GLView();
+        mGLView.setNearFrustum(5.0f);
+        mGLView.setFarFrustum(50.0f);
+        mGLView.setLightModelAmbientIntensity(0.225f);
+        mGLView.setAmbientIntensity(0.0f);
+        mGLView.setDiffuseIntensity(1.5f);
+        mGLView.setDiffuseColor(SUNLIGHT_COLOR);
+        mGLView.setSpecularIntensity(0.0f);
+        mGLView.setSpecularColor(SUNLIGHT_COLOR);
+
+        if (PERFORM_DEPTH_TEST) {
+            gl.glEnable(GL10.GL_DEPTH_TEST);
+        }
+        gl.glDisable(GL10.GL_SCISSOR_TEST);
+        gl.glClearColor(0, 0, 0, 1);
+        gl.glHint(GL10.GL_POINT_SMOOTH_HINT, GL10.GL_NICEST);
+
+        mInitialized = true;
+    }
+
+    /**
+     * Computes the vector from the center of the earth to the sun for a
+     * particular moment in time.
+     */
+    private void computeSunDirection() {
+        mSunCal.setTimeInMillis(System.currentTimeMillis());
+        int day = mSunCal.get(Calendar.DAY_OF_YEAR);
+        int seconds = 3600 * mSunCal.get(Calendar.HOUR_OF_DAY) +
+            60 * mSunCal.get(Calendar.MINUTE) + mSunCal.get(Calendar.SECOND);
+        day += (float) seconds / SECONDS_PER_DAY;
+
+        // Approximate declination of the sun, changes sinusoidally
+        // during the year.  The winter solstice occurs 10 days before
+        // the start of the year.
+        float decl = (float) (EARTH_INCLINATION *
+            Math.cos(Shape.TWO_PI * (day + 10) / 365.0));
+
+        // Subsolar latitude, convert from (-PI/2, PI/2) -> (0, PI) form
+        float phi = decl + Shape.PI_OVER_TWO;
+        // Subsolar longitude
+        float theta = Shape.TWO_PI * seconds / SECONDS_PER_DAY;
+
+        float sinPhi = (float) Math.sin(phi);
+        float cosPhi = (float) Math.cos(phi);
+        float sinTheta = (float) Math.sin(theta);
+        float cosTheta = (float) Math.cos(theta);
+
+        // Convert from polar to rectangular coordinates
+        float x = cosTheta * sinPhi;
+        float y = cosPhi;
+        float z = sinTheta * sinPhi;
+
+        // Directional light -> w == 0
+        mLightDir[0] = x;
+        mLightDir[1] = y;
+        mLightDir[2] = z;
+        mLightDir[3] = 0.0f;
+    }
+
+    /**
+     * Computes the approximate spherical distance between two
+     * (latitude, longitude) coordinates.
+     */
+    private float distance(float lat1, float lon1,
+                           float lat2, float lon2) {
+        lat1 *= Shape.DEGREES_TO_RADIANS;
+        lat2 *= Shape.DEGREES_TO_RADIANS;
+        lon1 *= Shape.DEGREES_TO_RADIANS;
+        lon2 *= Shape.DEGREES_TO_RADIANS;
+
+        float r = 6371.0f; // Earth's radius in km
+        float dlat = lat2 - lat1;
+        float dlon = lon2 - lon1;
+        double sinlat2 = Math.sin(dlat / 2.0f);
+        sinlat2 *= sinlat2;
+        double sinlon2 = Math.sin(dlon / 2.0f);
+        sinlon2 *= sinlon2;
+
+        double a = sinlat2 + Math.cos(lat1) * Math.cos(lat2) * sinlon2;
+        double c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+        return (float) (r * c);
+    }
+
+    /**
+     * Locates the closest city to the currently displayed center point,
+     * optionally restricting the search to cities within a given time zone.
+     */
+    private void locateCity(boolean useOffset, float offset) {
+        float mindist = Float.MAX_VALUE;
+        int minidx = -1;
+        for (int i = 0; i < mCities.size(); i++) {
+            City city = mCities.get(i);
+            if (useOffset && !tzEqual(getOffset(city), offset)) {
+                continue;
+            }
+            float dist = distance(city.getLatitude(), city.getLongitude(),
+                mTiltAngle, mRotAngle - 90.0f);
+            if (dist < mindist) {
+                mindist = dist;
+                minidx = i;
+            }
+        }
+
+        mCityIndex = minidx;
+    }
+
+    /**
+     * Animates the earth to be centered at the current city.
+     */
+    private void goToCity() {
+        City city = mCities.get(mCityIndex);
+        float dist = distance(city.getLatitude(), city.getLongitude(),
+            mTiltAngle, mRotAngle - 90.0f);
+
+        mFlyToCity = true;
+        mCityFlyStartTime = System.currentTimeMillis();
+        mCityFlightTime = dist / 5.0f; // 5000 km/sec
+        mRotAngleStart = mRotAngle;
+        mRotAngleDest = city.getLongitude() + 90;
+
+        if (mRotAngleDest - mRotAngleStart > 180.0f) {
+            mRotAngleDest -= 360.0f;
+        } else if (mRotAngleStart - mRotAngleDest > 180.0f) {
+            mRotAngleDest += 360.0f;
+        }
+
+        mTiltAngleStart = mTiltAngle;
+        mTiltAngleDest = city.getLatitude();
+        mRotVelocity = 0.0f;
+    }
+
+    /**
+     * Returns a linearly interpolated value between two values.
+     */
+    private float lerp(float a, float b, float lerp) {
+        return a + (b - a)*lerp;
+    }
+
+    /**
+     * Draws the city lights, using a clip plane to restrict the lights
+     * to the night side of the earth.
+     */
+    private void drawCityLights(GL10 gl, float brightness) {
+        gl.glEnable(GL10.GL_POINT_SMOOTH);
+        gl.glDisable(GL10.GL_DEPTH_TEST);
+        gl.glDisable(GL10.GL_LIGHTING);
+        gl.glDisable(GL10.GL_DITHER);
+        gl.glShadeModel(GL10.GL_FLAT);
+        gl.glEnable(GL10.GL_BLEND);
+        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
+        gl.glPointSize(1.0f);
+
+        float ls = lerp(0.8f, 0.3f, brightness);
+        gl.glColor4f(ls * 1.0f, ls * 1.0f, ls * 0.8f, 1.0f);
+
+        if (mDisplayWorld) {
+            mClipPlaneEquation[0] = -mLightDir[0];
+            mClipPlaneEquation[1] = -mLightDir[1];
+            mClipPlaneEquation[2] = -mLightDir[2];
+            mClipPlaneEquation[3] = 0.0f;
+            // Assume we have glClipPlanef() from OpenGL ES 1.1
+            ((GL11) gl).glClipPlanef(GL11.GL_CLIP_PLANE0,
+                mClipPlaneEquation, 0);
+            gl.glEnable(GL11.GL_CLIP_PLANE0);
+        }
+        mLights.draw(gl);
+        if (mDisplayWorld) {
+            gl.glDisable(GL11.GL_CLIP_PLANE0);
+        }
+
+        mNumTriangles += mLights.getNumTriangles()*2;
+    }
+
+    /**
+     * Draws the atmosphere.
+     */
+    private void drawAtmosphere(GL10 gl) {
+        gl.glDisable(GL10.GL_LIGHTING);
+        gl.glDisable(GL10.GL_CULL_FACE);
+        gl.glDisable(GL10.GL_DITHER);
+        gl.glDisable(GL10.GL_DEPTH_TEST);
+        gl.glShadeModel(mSmoothShading ? GL10.GL_SMOOTH : GL10.GL_FLAT);
+
+        // Draw the atmospheric layer
+        float tx = mGLView.getTranslateX();
+        float ty = mGLView.getTranslateY();
+        float tz = mGLView.getTranslateZ();
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(tx, ty, tz);
+
+        // Blend in the atmosphere a bit
+        gl.glEnable(GL10.GL_BLEND);
+        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
+        ATMOSPHERE.draw(gl);
+
+        mNumTriangles += ATMOSPHERE.getNumTriangles();
+    }
+
+    /**
+     * Draws the world in a 2D map view.
+     */
+    private void drawWorldFlat(GL10 gl) {
+        gl.glDisable(GL10.GL_BLEND);
+        gl.glEnable(GL10.GL_DITHER);
+        gl.glShadeModel(mSmoothShading ? GL10.GL_SMOOTH : GL10.GL_FLAT);
+
+        gl.glTranslatef(mWrapX - 2, 0.0f, 0.0f);
+        worldFlat.draw(gl);
+        gl.glTranslatef(2.0f, 0.0f, 0.0f);
+        worldFlat.draw(gl);
+        mNumTriangles += worldFlat.getNumTriangles() * 2;
+
+        mWrapX += mWrapVelocity * mWrapVelocityFactor;
+        while (mWrapX < 0.0f) {
+            mWrapX += 2.0f;
+        }
+        while (mWrapX > 2.0f) {
+            mWrapX -= 2.0f;
+        }
+    }
+
+    /**
+     * Draws the world in a 2D round view.
+     */
+    private void drawWorldRound(GL10 gl) {
+        gl.glDisable(GL10.GL_BLEND);
+        gl.glEnable(GL10.GL_DITHER);
+        gl.glShadeModel(mSmoothShading ? GL10.GL_SMOOTH : GL10.GL_FLAT);
+
+        mWorld.draw(gl);
+        mNumTriangles += mWorld.getNumTriangles();
+    }
+
+    /**
+     * Draws the clock.
+     *
+     * @param canvas the Canvas to draw to
+     * @param now the current time
+     * @param w the width of the screen
+     * @param h the height of the screen
+     * @param lerp controls the animation, between 0.0 and 1.0
+     */
+    private void drawClock(Canvas canvas,
+                           long now,
+                           int w, int h,
+                           float lerp) {
+        float clockAlpha = lerp(0.0f, 0.8f, lerp);
+        mClockShowing = clockAlpha > 0.0f;
+        if (clockAlpha > 0.0f) {
+            City city = mCities.get(mCityIndex);
+            mClock.setCity(city);
+            mClock.setTime(now);
+
+            float cx = w / 2.0f;
+            float cy = h / 2.0f;
+            float smallRadius = 18.0f;
+            float bigRadius = 0.75f * 0.5f * Math.min(w, h);
+            float radius = lerp(smallRadius, bigRadius, lerp);
+
+            // Only display left/right arrows if we are in a name search
+            boolean scrollingByName =
+                (mCityName.length() > 0) && (mCities.size() > 1);
+            mClock.drawClock(canvas, cx, cy, radius,
+                             clockAlpha,
+                             1.0f,
+                             lerp == 1.0f, lerp == 1.0f,
+                             !atEndOfTimeZone(-1),
+                             !atEndOfTimeZone(1),
+                             scrollingByName,
+                             mCityName.length());
+        }
+    }
+
+    /**
+     * Draws the 2D layer.
+     */
+    @Override protected void onDraw(Canvas canvas) {
+        long now = System.currentTimeMillis();
+        if (startTime != -1) {
+            startTime = -1;
+        }
+
+        int w = getWidth();
+        int h = getHeight();
+
+        // Interpolator for clock size, clock alpha, night lights intensity
+        float lerp = Math.min((now - mClockFadeTime)/1000.0f, 1.0f);
+        if (!mDisplayClock) {
+            // Clock is receding
+            lerp = 1.0f - lerp;
+        }
+        lerp = mClockSizeInterpolator.getInterpolation(lerp);
+
+        // we don't need to make sure OpenGL rendering is done because
+        // we're drawing in to a different surface
+
+        drawClock(canvas, now, w, h, lerp);
+
+        mGLView.showMessages(canvas);
+        mGLView.showStatistics(canvas, w);
+    }
+
+    /**
+     * Draws the 3D layer.
+     */
+    protected void drawOpenGLScene() {
+        long now = System.currentTimeMillis();
+        mNumTriangles = 0;
+
+        EGL10 egl = (EGL10)EGLContext.getEGL();
+        GL10 gl = (GL10)mEGLContext.getGL();
+
+        if (!mInitialized) {
+            init(gl);
+        }
+
+        int w = getWidth();
+        int h = getHeight();
+        gl.glViewport(0, 0, w, h);
+
+        gl.glEnable(GL10.GL_LIGHTING);
+        gl.glEnable(GL10.GL_LIGHT0);
+        gl.glEnable(GL10.GL_CULL_FACE);
+        gl.glFrontFace(GL10.GL_CCW);
+
+        float ratio = (float) w / h;
+        mGLView.setAspectRatio(ratio);
+
+        mGLView.setTextureParameters(gl);
+
+        if (PERFORM_DEPTH_TEST) {
+            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+        } else {
+            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
+        }
+
+        if (mDisplayWorldFlat) {
+            gl.glMatrixMode(GL10.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glFrustumf(-1.0f, 1.0f, -1.0f / ratio, 1.0f / ratio, 1.0f, 2.0f);
+            gl.glMatrixMode(GL10.GL_MODELVIEW);
+            gl.glLoadIdentity();
+            gl.glTranslatef(0.0f, 0.0f, -1.0f);
+        } else {
+            mGLView.setProjection(gl);
+            mGLView.setView(gl);
+        }
+
+        if (!mDisplayWorldFlat) {
+            if (mFlyToCity) {
+                float lerp = (now - mCityFlyStartTime)/mCityFlightTime;
+                if (lerp >= 1.0f) {
+                    mFlyToCity = false;
+                }
+                lerp = Math.min(lerp, 1.0f);
+                lerp = mFlyToCityInterpolator.getInterpolation(lerp);
+                mRotAngle = lerp(mRotAngleStart, mRotAngleDest, lerp);
+                mTiltAngle = lerp(mTiltAngleStart, mTiltAngleDest, lerp);
+            }
+
+            // Rotate the viewpoint around the earth
+            gl.glMatrixMode(GL10.GL_MODELVIEW);
+            gl.glRotatef(mTiltAngle, 1, 0, 0);
+            gl.glRotatef(mRotAngle, 0, 1, 0);
+
+            // Increment the rotation angle
+            mRotAngle += mRotVelocity;
+            if (mRotAngle < 0.0f) {
+                mRotAngle += 360.0f;
+            }
+            if (mRotAngle > 360.0f) {
+                mRotAngle -= 360.0f;
+            }
+        }
+
+        // Draw the world with lighting
+        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, mLightDir, 0);
+        mGLView.setLights(gl, GL10.GL_LIGHT0);
+
+        if (mDisplayWorldFlat) {
+            drawWorldFlat(gl);
+        } else if (mDisplayWorld) {
+            drawWorldRound(gl);
+        }
+
+        if (mDisplayLights && !mDisplayWorldFlat) {
+            // Interpolator for clock size, clock alpha, night lights intensity
+            float lerp = Math.min((now - mClockFadeTime)/1000.0f, 1.0f);
+            if (!mDisplayClock) {
+                // Clock is receding
+                lerp = 1.0f - lerp;
+            }
+            lerp = mClockSizeInterpolator.getInterpolation(lerp);
+            drawCityLights(gl, lerp);
+        }
+
+        if (mDisplayAtmosphere && !mDisplayWorldFlat) {
+            drawAtmosphere(gl);
+        }
+        mGLView.setNumTriangles(mNumTriangles);
+        egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
+
+        if (egl.eglGetError() == EGL11.EGL_CONTEXT_LOST) {
+            // we lost the gpu, quit immediately
+            Context c = getContext();
+            if (c instanceof Activity) {
+                ((Activity)c).finish();
+            }
+        }
+    }
+
+
+    private static final int INVALIDATE = 1;
+    private static final int ONE_MINUTE = 60000;
+
+    /**
+     * Controls the animation using the message queue.  Every time we receive
+     * an INVALIDATE message, we redraw and place another message in the queue.
+     */
+    private final Handler mHandler = new Handler() {
+        private long mLastSunPositionTime = 0;
+
+        @Override public void handleMessage(Message msg) {
+            if (msg.what == INVALIDATE) {
+
+                // Use the message's time, it's good enough and
+                // allows us to avoid a system call.
+                if ((msg.getWhen() - mLastSunPositionTime) >= ONE_MINUTE) {
+                    // Recompute the sun's position once per minute
+                    // Place the light at the Sun's direction
+                    computeSunDirection();
+                    mLastSunPositionTime = msg.getWhen();
+                }
+
+                // Draw the GL scene
+                drawOpenGLScene();
+
+                // Send an update for the 2D overlay if needed
+                if (mInitialized &&
+                                (mClockShowing || mGLView.hasMessages())) {
+                    invalidate();
+                }
+
+                // Just send another message immediately. This works because
+                // drawOpenGLScene() does the timing for us -- it will
+                // block until the last frame has been processed.
+                // The invalidate message we're posting here will be
+                // interleaved properly with motion/key events which
+                // guarantee a prompt reaction to the user input.
+                sendEmptyMessage(INVALIDATE);
+            }
+        }
+    };
+}
+
+/**
+ * The main activity class for GlobalTime.
+ */
+public class GlobalTime extends Activity {
+
+    GTView gtView = null;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        gtView = new GTView(this);
+        setContentView(gtView);
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        gtView.onResume();
+        Looper.myQueue().addIdleHandler(new Idler());
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        gtView.onPause();
+    }
+
+    @Override protected void onStop() {
+        super.onStop();
+        gtView.destroy();
+        gtView = null;
+    }
+
+    // Allow the activity to go idle before its animation starts
+    class Idler implements MessageQueue.IdleHandler {
+        public Idler() {
+            super();
+        }
+
+        public final boolean queueIdle() {
+            if (gtView != null) {
+                gtView.startAnimating();
+            }
+            return false;
+        }
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/LatLongSphere.java b/samples/GlobalTime/src/com/android/globaltime/LatLongSphere.java
new file mode 100644
index 0000000..b455d41
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/LatLongSphere.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+public class LatLongSphere extends Sphere {
+
+    public LatLongSphere(float centerX, float centerY, float centerZ,
+        float radius, int lats, int longs,
+        float minLongitude, float maxLongitude,
+        boolean emitTextureCoordinates,
+        boolean emitNormals,
+        boolean emitColors,
+        boolean flatten) {
+        super(emitTextureCoordinates, emitNormals, emitColors);
+
+        int tris = 2 * (lats - 1) * (longs - 1);
+        int[] vertices = new int[3 * lats * longs];
+        int[] texcoords = new int[2 * lats * longs];
+        int[] colors = new int[4 * lats * longs];
+        int[] normals = new int[3 * lats * longs];
+        short[] indices = new short[3 * tris];
+
+        int vidx = 0;
+        int tidx = 0;
+        int nidx = 0;
+        int cidx = 0;
+        int iidx = 0;
+
+        minLongitude *= DEGREES_TO_RADIANS;
+        maxLongitude *= DEGREES_TO_RADIANS;
+
+        for (int i = 0; i < longs; i++) {
+            float fi = (float) i / (longs - 1);
+            // theta is the longitude
+            float theta =
+                (maxLongitude - minLongitude) * (1.0f - fi) + minLongitude;
+            float sinTheta = (float) Math.sin(theta);
+            float cosTheta = (float) Math.cos(theta);
+
+            for (int j = 0; j < lats; j++) {
+                float fj = (float) j / (lats - 1);
+                // phi is the latitude
+                float phi = PI * fj;
+                float sinPhi = (float) Math.sin(phi);
+                float cosPhi = (float) Math.cos(phi);
+                float x = cosTheta * sinPhi;
+                float y = cosPhi;
+                float z = sinTheta * sinPhi;
+
+                if (flatten) {
+                    // Place vertices onto a flat projection
+                    vertices[vidx++] = toFixed(2.0f * fi - 1.0f);
+                    vertices[vidx++] = toFixed(0.5f - fj);
+                    vertices[vidx++] = toFixed(0.0f);
+                } else {
+                    // Place vertices onto the surface of a sphere
+                    // with the given center and radius
+                    vertices[vidx++] = toFixed(x * radius + centerX);
+                    vertices[vidx++] = toFixed(y * radius + centerY);
+                    vertices[vidx++] = toFixed(z * radius + centerZ);
+                }
+
+                if (emitTextureCoordinates) {
+                    texcoords[tidx++] = toFixed(1.0f - (theta / (TWO_PI)));
+                    texcoords[tidx++] = toFixed(fj);
+                }
+
+                if (emitNormals) {
+                    float norm = 1.0f / Shape.length(x, y, z);
+                    normals[nidx++] = toFixed(x * norm);
+                    normals[nidx++] = toFixed(y * norm);
+                    normals[nidx++] = toFixed(z * norm);
+                }
+
+                // 0 == black, 65536 == white
+                if (emitColors) {
+                    colors[cidx++] = (i % 2) * 65536;
+                    colors[cidx++] = 0;
+                    colors[cidx++] = (j % 2) * 65536;
+                    colors[cidx++] = 65536;
+                }
+            }
+        }
+
+        for (int i = 0; i < longs - 1; i++) {
+            for (int j = 0; j < lats - 1; j++) {
+                int base = i * lats + j;
+
+                // Ensure both triangles have the same final vertex
+                // since this vertex carries the color for flat
+                // shading
+                indices[iidx++] = (short) (base);
+                indices[iidx++] = (short) (base + 1);
+                indices[iidx++] = (short) (base + lats + 1);
+
+                indices[iidx++] = (short) (base + lats);
+                indices[iidx++] = (short) (base);
+                indices[iidx++] = (short) (base + lats + 1);
+            }
+        }
+        
+        allocateBuffers(vertices, texcoords, normals, colors, indices);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/PointCloud.java b/samples/GlobalTime/src/com/android/globaltime/PointCloud.java
new file mode 100644
index 0000000..6f4fd55
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/PointCloud.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A class representing a set of GL_POINT objects.  GlobalTime uses this class
+ * to draw city lights on the night side of the earth.
+ */
+public class PointCloud extends Shape {
+
+    /**
+     * Constructs a PointCloud with a point at each of the given vertex
+     * (x, y, z) positions.
+     * @param vertices an array of (x, y, z) positions given in fixed-point.
+     */
+    public PointCloud(int[] vertices) {
+        this(vertices, 0, vertices.length);
+    }
+
+    /**
+     * Constructs a PointCloud with a point at each of the given vertex
+     * (x, y, z) positions.
+     * @param vertices an array of (x, y, z) positions given in fixed-point.
+     * @param off the starting offset of the vertices array
+     * @param len the number of elements of the vertices array to use
+     */
+    public PointCloud(int[] vertices, int off, int len) {
+        super(GL10.GL_POINTS, GL10.GL_UNSIGNED_SHORT,
+              false, false, false);
+
+        int numPoints = len / 3;
+        short[] indices = new short[numPoints];
+        for (int i = 0; i < numPoints; i++) {
+            indices[i] = (short)i;
+        }
+        
+        allocateBuffers(vertices, null, null, null, indices);
+        this.mNumIndices = mIndexBuffer.capacity();
+    }
+
+    @Override public int getNumTriangles() {
+        return mNumIndices * 2;
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/Shape.java b/samples/GlobalTime/src/com/android/globaltime/Shape.java
new file mode 100644
index 0000000..6c296ce
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/Shape.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * An abstract superclass for various three-dimensional objects to be drawn
+ * using OpenGL ES.  Each subclass is responsible for setting up NIO buffers
+ * containing vertices, texture coordinates, colors, normals, and indices.
+ * The {@link #draw(GL10)} method draws the object to the given OpenGL context.
+ */
+public abstract class Shape {
+
+    public static final int INT_BYTES = 4;
+    public static final int SHORT_BYTES = 2;
+
+    public static final float DEGREES_TO_RADIANS = (float) Math.PI / 180.0f;
+    public static final float PI = (float) Math.PI;
+    public static final float TWO_PI = (float) (2.0 * Math.PI);
+    public static final float PI_OVER_TWO = (float) (Math.PI / 2.0);
+
+    protected int mPrimitive;
+    protected int mIndexDatatype;
+
+    protected boolean mEmitTextureCoordinates;
+    protected boolean mEmitNormals;
+    protected boolean mEmitColors;
+
+    protected IntBuffer mVertexBuffer;
+    protected IntBuffer mTexcoordBuffer;
+    protected IntBuffer mColorBuffer;
+    protected IntBuffer mNormalBuffer;
+    protected Buffer mIndexBuffer;
+    protected int mNumIndices = -1;
+
+    /**
+     * Constructs a Shape.
+     * 
+     * @param primitive a GL primitive type understood by glDrawElements,
+     * such as GL10.GL_TRIANGLES
+     * @param indexDatatype the GL datatype for the  index buffer, such as
+     * GL10.GL_UNSIGNED_SHORT
+     * @param emitTextureCoordinates true to enable use of the texture
+     * coordinate buffer
+     * @param emitNormals true to enable use of the normal buffer
+     * @param emitColors true to enable use of the color buffer
+     */
+    protected Shape(int primitive,
+        int indexDatatype,
+        boolean emitTextureCoordinates,
+        boolean emitNormals,
+        boolean emitColors) {
+        mPrimitive = primitive;
+        mIndexDatatype = indexDatatype;
+        mEmitTextureCoordinates = emitTextureCoordinates;
+        mEmitNormals = emitNormals;
+        mEmitColors = emitColors;
+    }
+
+    /**
+     * Converts the given floating-point value to fixed-point.
+     */
+    public static int toFixed(float x) {
+        return (int) (x * 65536.0);
+    }
+
+    /**
+     * Converts the given fixed-point value to floating-point.
+     */
+    public static float toFloat(int x) {
+        return (float) (x / 65536.0);
+    }
+
+    /**
+     * Computes the cross-product of two vectors p and q and places
+     * the result in out. 
+     */
+    public static void cross(float[] p, float[] q, float[] out) {
+        out[0] = p[1] * q[2] - p[2] * q[1];
+        out[1] = p[2] * q[0] - p[0] * q[2];
+        out[2] = p[0] * q[1] - p[1] * q[0];
+    }
+
+    /**
+     * Returns the length of a vector, given as three floats.
+     */
+    public static float length(float vx, float vy, float vz) {
+        return (float) Math.sqrt(vx * vx + vy * vy + vz * vz);
+    }
+
+    /**
+     * Returns the length of a vector, given as an array of three floats.
+     */
+    public static float length(float[] v) { 
+        return length(v[0], v[1], v[2]);
+    }
+
+    /**
+     * Normalizes the given vector of three floats to have length == 1.0.
+     * Vectors with length zero are unaffected.
+     */
+    public static void normalize(float[] v) {
+        float length = length(v);
+        if (length != 0.0f) {
+            float norm = 1.0f / length;
+            v[0] *= norm;
+            v[1] *= norm;
+            v[2] *= norm;
+        }
+    }
+
+    /**
+     * Returns the number of triangles associated with this shape.
+     */
+    public int getNumTriangles() {
+        if (mPrimitive == GL10.GL_TRIANGLES) {
+            return mIndexBuffer.capacity() / 3;
+        } else if (mPrimitive == GL10.GL_TRIANGLE_STRIP) {
+            return mIndexBuffer.capacity() - 2;
+        }
+        return 0;
+    }
+    
+    /**
+     * Copies the given data into the instance
+     * variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
+     * and mIndexBuffer.
+     * 
+     * @param vertices an array of fixed-point vertex coordinates
+     * @param texcoords an array of fixed-point texture coordinates
+     * @param normals an array of fixed-point normal vector coordinates
+     * @param colors an array of fixed-point color channel values
+     * @param indices an array of short indices
+     */
+    public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
+        int[] colors, short[] indices) {
+        allocate(vertices, texcoords, normals, colors);
+        
+        ByteBuffer ibb =
+            ByteBuffer.allocateDirect(indices.length * SHORT_BYTES);
+        ibb.order(ByteOrder.nativeOrder());
+        ShortBuffer shortIndexBuffer = ibb.asShortBuffer();
+        shortIndexBuffer.put(indices);
+        shortIndexBuffer.position(0);
+        this.mIndexBuffer = shortIndexBuffer;
+    }
+    
+    /**
+     * Copies the given data into the instance
+     * variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
+     * and mIndexBuffer.
+     * 
+     * @param vertices an array of fixed-point vertex coordinates
+     * @param texcoords an array of fixed-point texture coordinates
+     * @param normals an array of fixed-point normal vector coordinates
+     * @param colors an array of fixed-point color channel values
+     * @param indices an array of int indices
+     */
+    public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
+        int[] colors, int[] indices) {
+        allocate(vertices, texcoords, normals, colors);
+        
+        ByteBuffer ibb =
+            ByteBuffer.allocateDirect(indices.length * INT_BYTES);
+        ibb.order(ByteOrder.nativeOrder());
+        IntBuffer intIndexBuffer = ibb.asIntBuffer();
+        intIndexBuffer.put(indices);
+        intIndexBuffer.position(0);
+        this.mIndexBuffer = intIndexBuffer;
+    }
+    
+    /**
+     * Allocate the vertex, texture coordinate, normal, and color buffer.
+     */
+    private void allocate(int[] vertices, int[] texcoords, int[] normals,
+        int[] colors) {
+        ByteBuffer vbb =
+            ByteBuffer.allocateDirect(vertices.length * INT_BYTES);
+        vbb.order(ByteOrder.nativeOrder());
+        mVertexBuffer = vbb.asIntBuffer();
+        mVertexBuffer.put(vertices);
+        mVertexBuffer.position(0);
+
+        if ((texcoords != null) && mEmitTextureCoordinates) {
+            ByteBuffer tbb =
+                ByteBuffer.allocateDirect(texcoords.length * INT_BYTES);
+            tbb.order(ByteOrder.nativeOrder());
+            mTexcoordBuffer = tbb.asIntBuffer();
+            mTexcoordBuffer.put(texcoords);
+            mTexcoordBuffer.position(0);
+        }
+
+        if ((normals != null) && mEmitNormals) {
+            ByteBuffer nbb =
+                ByteBuffer.allocateDirect(normals.length * INT_BYTES);
+            nbb.order(ByteOrder.nativeOrder());
+            mNormalBuffer = nbb.asIntBuffer();
+            mNormalBuffer.put(normals);
+            mNormalBuffer.position(0);
+        }
+
+        if ((colors != null) && mEmitColors) {
+            ByteBuffer cbb =
+                ByteBuffer.allocateDirect(colors.length * INT_BYTES);
+            cbb.order(ByteOrder.nativeOrder());
+            mColorBuffer = cbb.asIntBuffer();
+            mColorBuffer.put(colors);
+            mColorBuffer.position(0);
+        }
+    }
+
+    /**
+     * Draws the shape to the given OpenGL ES 1.0 context.  Texture coordinates,
+     * normals, and colors are emitted according the the preferences set for
+     * this shape.
+     */
+    public void draw(GL10 gl) {
+        gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+
+        if (mEmitTextureCoordinates) {
+            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+            gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTexcoordBuffer);
+            gl.glEnable(GL10.GL_TEXTURE_2D);
+        } else {
+            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+            gl.glDisable(GL10.GL_TEXTURE_2D);
+        }
+
+        if (mEmitNormals) {
+            gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
+            gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);
+        } else {
+            gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
+        }
+
+        if (mEmitColors) {
+            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+            gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
+        } else {
+            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
+        }
+
+        gl.glDrawElements(mPrimitive,
+                          mNumIndices > 0 ? mNumIndices : mIndexBuffer.capacity(),
+                          mIndexDatatype,
+                          mIndexBuffer);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/Sphere.java b/samples/GlobalTime/src/com/android/globaltime/Sphere.java
new file mode 100644
index 0000000..4dff05d
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/Sphere.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import javax.microedition.khronos.opengles.GL10;
+
+public class Sphere extends Shape {
+
+    public Sphere(boolean emitTextureCoordinates,
+        boolean emitNormals, boolean emitColors) {
+        super(GL10.GL_TRIANGLES, GL10.GL_UNSIGNED_SHORT,
+              emitTextureCoordinates, emitNormals, emitColors);
+    }
+}
diff --git a/samples/GlobalTime/src/com/android/globaltime/Texture.java b/samples/GlobalTime/src/com/android/globaltime/Texture.java
new file mode 100644
index 0000000..ee3af00
--- /dev/null
+++ b/samples/GlobalTime/src/com/android/globaltime/Texture.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.globaltime;
+
+import java.nio.ByteBuffer;
+
+public class Texture {
+
+    private ByteBuffer data;
+    private int width, height;
+
+    public Texture(ByteBuffer data, int width, int height) {
+        this.data = data;
+        this.width = width;
+        this.height = height;
+    }
+
+    public ByteBuffer getData() {
+        return data;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+}
diff --git a/samples/HelloActivity/Android.mk b/samples/HelloActivity/Android.mk
new file mode 100644
index 0000000..7f54bdb
--- /dev/null
+++ b/samples/HelloActivity/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 := HelloActivity
+
+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/HelloActivity/AndroidManifest.xml b/samples/HelloActivity/AndroidManifest.xml
new file mode 100644
index 0000000..9551e54
--- /dev/null
+++ b/samples/HelloActivity/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.helloactivity">
+    <application android:label="Hello, Activity!">
+        <activity android:name="HelloActivity">
+            <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/HelloActivity/res/layout/hello_activity.xml b/samples/HelloActivity/res/layout/hello_activity.xml
new file mode 100644
index 0000000..2a4d2de
--- /dev/null
+++ b/samples/HelloActivity/res/layout/hello_activity.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:textSize="18sp"
+    android:autoText="true"
+    android:capitalize="sentences"
+    android:text="@string/hello_activity_text_text" />
+
diff --git a/samples/HelloActivity/res/values/strings.xml b/samples/HelloActivity/res/values/strings.xml
new file mode 100644
index 0000000..7eab42c
--- /dev/null
+++ b/samples/HelloActivity/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+
+    <string name="hello_activity_text_text">Hello, World!</string>
+
+</resources>
diff --git a/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java b/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java
new file mode 100644
index 0000000..62bf5ca
--- /dev/null
+++ b/samples/HelloActivity/src/com/example/android/helloactivity/HelloActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.helloactivity;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+/**
+ * A minimal "Hello, World!" application.
+ */
+public class HelloActivity extends Activity {
+    public HelloActivity() {
+    }
+
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Set the layout for this activity.  You can find it
+        // in res/layout/hello_activity.xml
+        setContentView(R.layout.hello_activity);
+    }
+}
+
diff --git a/samples/HelloActivity/tests/Android.mk b/samples/HelloActivity/tests/Android.mk
new file mode 100644
index 0000000..abd9a8e
--- /dev/null
+++ b/samples/HelloActivity/tests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := HelloActivityTests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_INSTRUMENTATION_FOR := HelloActivity
+
+include $(BUILD_PACKAGE)
diff --git a/samples/HelloActivity/tests/AndroidManifest.xml b/samples/HelloActivity/tests/AndroidManifest.xml
new file mode 100644
index 0000000..5294d07
--- /dev/null
+++ b/samples/HelloActivity/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.helloactivity.tests">
+
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+  <instrumentation android:name="android.test.InstrumentationTestRunner"
+      android:targetPackage="com.example.android.helloactivity"
+      android:label="HelloActivity sample tests">
+  </instrumentation>  
+  
+</manifest>
diff --git a/samples/HelloActivity/tests/src/com/example/android/helloactivity/HelloActivityTest.java b/samples/HelloActivity/tests/src/com/example/android/helloactivity/HelloActivityTest.java
new file mode 100644
index 0000000..6e032da
--- /dev/null
+++ b/samples/HelloActivity/tests/src/com/example/android/helloactivity/HelloActivityTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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.helloactivity;
+
+import android.test.ActivityInstrumentationTestCase;
+
+import com.example.android.helloactivity.HelloActivity;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class HelloActivityTest extends ActivityInstrumentationTestCase<HelloActivity> {
+
+  public HelloActivityTest() {
+      super("com.example.android.helloactivity", HelloActivity.class);
+  }
+  
+}
diff --git a/samples/Home/Android.mk b/samples/Home/Android.mk
new file mode 100644
index 0000000..ddc1851
--- /dev/null
+++ b/samples/Home/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_PACKAGE_NAME := Home
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/samples/Home/AndroidManifest.xml b/samples/Home/AndroidManifest.xml
new file mode 100644
index 0000000..229171f
--- /dev/null
+++ b/samples/Home/AndroidManifest.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/Home/AndroidManifest.xml
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.home">
+    <uses-permission android:name="android.permission.CALL_PHONE"/>
+    <uses-permission android:name="android.permission.GET_TASKS"/>
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+    <uses-permission android:name="android.permission.SET_WALLPAPER" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
+
+    <application android:persistent="true"
+          android:label="@string/home_title"
+          android:icon="@drawable/ic_launcher_home">
+
+        <activity android:name="Home"
+                android:theme="@style/Theme"
+                android:launchMode="singleInstance"
+                android:stateNotNeeded="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.HOME"/>
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="Wallpaper"
+                android:label="Wallpaper"
+                android:icon="@drawable/bg_android_icon">
+            <intent-filter>
+                <action android:name="android.intent.action.SET_WALLPAPER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/samples/Home/MODULE_LICENSE_APACHE2 b/samples/Home/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/Home/MODULE_LICENSE_APACHE2
diff --git a/samples/Home/NOTICE b/samples/Home/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/samples/Home/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/samples/Home/res/anim/fade_in.xml b/samples/Home/res/anim/fade_in.xml
new file mode 100644
index 0000000..fe38ab1
--- /dev/null
+++ b/samples/Home/res/anim/fade_in.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator"
+    android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="50" />
diff --git a/samples/Home/res/anim/fade_out.xml b/samples/Home/res/anim/fade_out.xml
new file mode 100644
index 0000000..64ac4f9
--- /dev/null
+++ b/samples/Home/res/anim/fade_out.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator"
+    android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="50" />
diff --git a/samples/Home/res/anim/grid_entry.xml b/samples/Home/res/anim/grid_entry.xml
new file mode 100644
index 0000000..330c07d
--- /dev/null
+++ b/samples/Home/res/anim/grid_entry.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/fade_in.xml
+**
+** Copyright 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:interpolator="@android:anim/decelerate_interpolator">
+    <scale android:fromXScale="0.8" android:toXScale="1.0"
+           android:fromYScale="0.9" android:toYScale="1.0"
+           android:pivotX="100%" android:pivotY="100%" android:duration="200" />
+    <alpha android:fromAlpha="0.5" android:toAlpha="1.0" android:duration="200" />
+</set>
diff --git a/samples/Home/res/anim/grid_exit.xml b/samples/Home/res/anim/grid_exit.xml
new file mode 100644
index 0000000..c9baf2a
--- /dev/null
+++ b/samples/Home/res/anim/grid_exit.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator"
+    android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="200" />
diff --git a/samples/Home/res/anim/hide_applications.xml b/samples/Home/res/anim/hide_applications.xml
new file mode 100644
index 0000000..93039a8
--- /dev/null
+++ b/samples/Home/res/anim/hide_applications.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:rowDelay="25%"
+        android:directionPriority="column"
+        android:animation="@anim/fade_out" />
diff --git a/samples/Home/res/anim/show_applications.xml b/samples/Home/res/anim/show_applications.xml
new file mode 100644
index 0000000..a97c99c
--- /dev/null
+++ b/samples/Home/res/anim/show_applications.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+        android:rowDelay="25%"
+        android:directionPriority="column"
+        android:direction="right_to_left|bottom_to_top"
+        android:animation="@anim/fade_in" />
diff --git a/samples/Home/res/color/bright_text_dark_focused.xml b/samples/Home/res/color/bright_text_dark_focused.xml
new file mode 100644
index 0000000..3b54573
--- /dev/null
+++ b/samples/Home/res/color/bright_text_dark_focused.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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_selected="true" android:color="#000" />
+    <item android:state_focused="true" android:color="#000" />
+    <item android:state_pressed="true" android:color="#000" />
+    <item android:color="#FFF" />
+</selector>
+
diff --git a/samples/Home/res/drawable-land/bg_android.jpg b/samples/Home/res/drawable-land/bg_android.jpg
new file mode 100644
index 0000000..0bd005f
--- /dev/null
+++ b/samples/Home/res/drawable-land/bg_android.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-land/bg_android_icon.jpg b/samples/Home/res/drawable-land/bg_android_icon.jpg
new file mode 100644
index 0000000..2619ef9
--- /dev/null
+++ b/samples/Home/res/drawable-land/bg_android_icon.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-land/bg_sunrise.jpg b/samples/Home/res/drawable-land/bg_sunrise.jpg
new file mode 100644
index 0000000..aa5a7d1
--- /dev/null
+++ b/samples/Home/res/drawable-land/bg_sunrise.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-land/bg_sunrise_icon.jpg b/samples/Home/res/drawable-land/bg_sunrise_icon.jpg
new file mode 100644
index 0000000..4972d8d
--- /dev/null
+++ b/samples/Home/res/drawable-land/bg_sunrise_icon.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-land/bg_sunset.jpg b/samples/Home/res/drawable-land/bg_sunset.jpg
new file mode 100644
index 0000000..0fc885b
--- /dev/null
+++ b/samples/Home/res/drawable-land/bg_sunset.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-land/bg_sunset_icon.jpg b/samples/Home/res/drawable-land/bg_sunset_icon.jpg
new file mode 100644
index 0000000..939edf7
--- /dev/null
+++ b/samples/Home/res/drawable-land/bg_sunset_icon.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-port/bg_android.jpg b/samples/Home/res/drawable-port/bg_android.jpg
new file mode 100644
index 0000000..cbbf3b9
--- /dev/null
+++ b/samples/Home/res/drawable-port/bg_android.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-port/bg_android_icon.jpg b/samples/Home/res/drawable-port/bg_android_icon.jpg
new file mode 100644
index 0000000..d5742b6
--- /dev/null
+++ b/samples/Home/res/drawable-port/bg_android_icon.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-port/bg_sunrise.jpg b/samples/Home/res/drawable-port/bg_sunrise.jpg
new file mode 100644
index 0000000..a69d5da
--- /dev/null
+++ b/samples/Home/res/drawable-port/bg_sunrise.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-port/bg_sunrise_icon.jpg b/samples/Home/res/drawable-port/bg_sunrise_icon.jpg
new file mode 100644
index 0000000..96968bc
--- /dev/null
+++ b/samples/Home/res/drawable-port/bg_sunrise_icon.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-port/bg_sunset.jpg b/samples/Home/res/drawable-port/bg_sunset.jpg
new file mode 100644
index 0000000..7135bd3
--- /dev/null
+++ b/samples/Home/res/drawable-port/bg_sunset.jpg
Binary files differ
diff --git a/samples/Home/res/drawable-port/bg_sunset_icon.jpg b/samples/Home/res/drawable-port/bg_sunset_icon.jpg
new file mode 100644
index 0000000..4ced6a9
--- /dev/null
+++ b/samples/Home/res/drawable-port/bg_sunset_icon.jpg
Binary files differ
diff --git a/samples/Home/res/drawable/all_applications.xml b/samples/Home/res/drawable/all_applications.xml
new file mode 100644
index 0000000..5703c68
--- /dev/null
+++ b/samples/Home/res/drawable/all_applications.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/checkbox.xml
+**
+** Copyright 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.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="false" android:drawable="@drawable/ic_launcher_allshow" />
+    <item android:state_checked="true" android:drawable="@drawable/ic_launcher_allhide" />
+</selector>
+
diff --git a/samples/Home/res/drawable/all_applications_background.xml b/samples/Home/res/drawable/all_applications_background.xml
new file mode 100644
index 0000000..69f5114
--- /dev/null
+++ b/samples/Home/res/drawable/all_applications_background.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/checkbox_background.xml
+**
+** Copyright 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.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/all_applications_label_background" />
+</selector>
diff --git a/samples/Home/res/drawable/all_applications_button_background.xml b/samples/Home/res/drawable/all_applications_button_background.xml
new file mode 100644
index 0000000..d7bdbd8
--- /dev/null
+++ b/samples/Home/res/drawable/all_applications_button_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/checkbox.xml
+**
+** Copyright 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.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/pressed_application_background_static" />
+    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/pressed_application_background_static" />
+    <item android:state_focused="true" android:drawable="@drawable/focused_application_background_static" />
+    <item android:state_focused="false" android:drawable="@drawable/application_background_static" />
+</selector>
+
diff --git a/samples/Home/res/drawable/all_applications_label_background.9.png b/samples/Home/res/drawable/all_applications_label_background.9.png
new file mode 100644
index 0000000..b1bf466
--- /dev/null
+++ b/samples/Home/res/drawable/all_applications_label_background.9.png
Binary files differ
diff --git a/samples/Home/res/drawable/application_background.9.png b/samples/Home/res/drawable/application_background.9.png
new file mode 100644
index 0000000..29ae09a
--- /dev/null
+++ b/samples/Home/res/drawable/application_background.9.png
Binary files differ
diff --git a/samples/Home/res/drawable/application_background_static.png b/samples/Home/res/drawable/application_background_static.png
new file mode 100644
index 0000000..9af6983
--- /dev/null
+++ b/samples/Home/res/drawable/application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable/favorite_background.xml b/samples/Home/res/drawable/favorite_background.xml
new file mode 100644
index 0000000..6d6a69c
--- /dev/null
+++ b/samples/Home/res/drawable/favorite_background.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/checkbox.xml
+**
+** Copyright 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.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/pressed_application_background_static" />
+    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/pressed_application_background_static" />
+    <item android:state_focused="true" android:drawable="@drawable/focused_application_background_static" />
+    <item android:state_focused="false" android:drawable="@android:color/transparent" />
+</selector>
diff --git a/samples/Home/res/drawable/focused_application_background_static.png b/samples/Home/res/drawable/focused_application_background_static.png
new file mode 100644
index 0000000..3a6d47c
--- /dev/null
+++ b/samples/Home/res/drawable/focused_application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable/grid_selector.xml b/samples/Home/res/drawable/grid_selector.xml
new file mode 100644
index 0000000..1116d35
--- /dev/null
+++ b/samples/Home/res/drawable/grid_selector.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/pressed_application_background_static" />
+    <item android:state_window_focused="false" android:drawable="@drawable/focused_application_background_static" />
+    <item android:state_window_focused="true" android:drawable="@drawable/focused_application_background_static" />
+</selector>
diff --git a/samples/Home/res/drawable/hide_all_applications.png b/samples/Home/res/drawable/hide_all_applications.png
new file mode 100644
index 0000000..a67cf78
--- /dev/null
+++ b/samples/Home/res/drawable/hide_all_applications.png
Binary files differ
diff --git a/samples/Home/res/drawable/ic_launcher_allhide.png b/samples/Home/res/drawable/ic_launcher_allhide.png
new file mode 100755
index 0000000..38e125d
--- /dev/null
+++ b/samples/Home/res/drawable/ic_launcher_allhide.png
Binary files differ
diff --git a/samples/Home/res/drawable/ic_launcher_allshow.png b/samples/Home/res/drawable/ic_launcher_allshow.png
new file mode 100755
index 0000000..5803d32
--- /dev/null
+++ b/samples/Home/res/drawable/ic_launcher_allshow.png
Binary files differ
diff --git a/samples/Home/res/drawable/ic_launcher_home.png b/samples/Home/res/drawable/ic_launcher_home.png
new file mode 100755
index 0000000..84af2a2
--- /dev/null
+++ b/samples/Home/res/drawable/ic_launcher_home.png
Binary files differ
diff --git a/samples/Home/res/drawable/pressed_application_background_static.png b/samples/Home/res/drawable/pressed_application_background_static.png
new file mode 100644
index 0000000..b086a3f
--- /dev/null
+++ b/samples/Home/res/drawable/pressed_application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable/show_all_applications.png b/samples/Home/res/drawable/show_all_applications.png
new file mode 100644
index 0000000..ed581e1
--- /dev/null
+++ b/samples/Home/res/drawable/show_all_applications.png
Binary files differ
diff --git a/samples/Home/res/layout-land/home.xml b/samples/Home/res/layout-land/home.xml
new file mode 100644
index 0000000..d723c69
--- /dev/null
+++ b/samples/Home/res/layout-land/home.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:home="http://schemas.android.com/apk/res/com.example.android.home"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <!-- All applications on the top side of the screen -->
+    <GridView android:id="@+id/all_apps"
+        android:background="@drawable/application_background"
+        android:persistentDrawingCache="animation|scrolling"
+        android:alwaysDrawnWithCache="true"
+        android:scrollbars="none"
+        android:drawSelectorOnTop="false"
+        android:listSelector="@drawable/grid_selector"
+        android:numColumns="auto_fit"
+        android:columnWidth="78dp"
+        android:stretchMode="spacingWidth"
+        android:layout_weight="1.0"
+        android:layout_height="0dip"
+        android:layout_width="fill_parent"
+        android:stackFromBottom="true"
+        android:visibility="invisible" />
+
+    <!-- Favorites and Recents -->
+    <com.example.android.home.ApplicationsStackLayout android:id="@+id/faves_and_recents"
+        home:stackOrientation="horizontal"
+        home:marginLeft="1dip"
+        home:marginRight="1dip"
+        android:layout_marginTop="0dip"
+        android:layout_width="fill_parent"
+        android:layout_height="65dip"
+        android:background="@drawable/application_background" />
+
+</LinearLayout>
diff --git a/samples/Home/res/layout-port/home.xml b/samples/Home/res/layout-port/home.xml
new file mode 100644
index 0000000..d723c69
--- /dev/null
+++ b/samples/Home/res/layout-port/home.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:home="http://schemas.android.com/apk/res/com.example.android.home"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <!-- All applications on the top side of the screen -->
+    <GridView android:id="@+id/all_apps"
+        android:background="@drawable/application_background"
+        android:persistentDrawingCache="animation|scrolling"
+        android:alwaysDrawnWithCache="true"
+        android:scrollbars="none"
+        android:drawSelectorOnTop="false"
+        android:listSelector="@drawable/grid_selector"
+        android:numColumns="auto_fit"
+        android:columnWidth="78dp"
+        android:stretchMode="spacingWidth"
+        android:layout_weight="1.0"
+        android:layout_height="0dip"
+        android:layout_width="fill_parent"
+        android:stackFromBottom="true"
+        android:visibility="invisible" />
+
+    <!-- Favorites and Recents -->
+    <com.example.android.home.ApplicationsStackLayout android:id="@+id/faves_and_recents"
+        home:stackOrientation="horizontal"
+        home:marginLeft="1dip"
+        home:marginRight="1dip"
+        android:layout_marginTop="0dip"
+        android:layout_width="fill_parent"
+        android:layout_height="65dip"
+        android:background="@drawable/application_background" />
+
+</LinearLayout>
diff --git a/samples/Home/res/layout/all_applications_button.xml b/samples/Home/res/layout/all_applications_button.xml
new file mode 100644
index 0000000..88430b3
--- /dev/null
+++ b/samples/Home/res/layout/all_applications_button.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/show_all_apps"
+    android:layout_width="78dip"
+    android:layout_height="65dip"
+    android:orientation="vertical"
+    android:gravity="center_vertical"
+    android:clickable="true"
+    android:focusable="true"    
+    android:background="@drawable/all_applications_button_background">
+
+    <CheckBox
+        android:id="@+id/show_all_apps_check"
+        android:focusable="false"
+        android:clickable="false"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/all_applications_background"
+        android:button="@drawable/all_applications"
+        android:text="@string/show_all_apps"
+        android:textSize="12dip"
+        android:maxLines="1"
+        android:duplicateParentState="true"            
+        android:textColor="@color/bright_text_dark_focused"
+        android:gravity="center_horizontal" />
+
+</LinearLayout>
diff --git a/samples/Home/res/layout/application.xml b/samples/Home/res/layout/application.xml
new file mode 100644
index 0000000..4ddc96e
--- /dev/null
+++ b/samples/Home/res/layout/application.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/label"
+    android:layout_width="78dip"
+    android:layout_height="65dip"
+    android:paddingTop="4dip"
+    android:textSize="12dip"
+    android:singleLine="true"
+    android:ellipsize="end"
+    android:textColor="@color/bright_text_dark_focused"
+    android:gravity="center_horizontal|center_vertical" />
diff --git a/samples/Home/res/layout/favorite.xml b/samples/Home/res/layout/favorite.xml
new file mode 100644
index 0000000..e100a43
--- /dev/null
+++ b/samples/Home/res/layout/favorite.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="78dip"
+    android:layout_height="65dip"
+    android:paddingTop="3dip"
+    android:paddingBottom="3dip"
+    android:clickable="true"
+    android:focusable="true"
+    android:background="@drawable/favorite_background"
+    android:textSize="12dip"
+    android:maxLines="1"
+    android:ellipsize="end"
+    android:textColor="@color/bright_text_dark_focused"
+    android:gravity="center_horizontal|bottom" />
diff --git a/samples/Home/res/layout/wallpaper.xml b/samples/Home/res/layout/wallpaper.xml
new file mode 100644
index 0000000..92dc65e
--- /dev/null
+++ b/samples/Home/res/layout/wallpaper.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/image_switcher_1.xml
+**
+** Copyright 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.
+*/
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent"> 
+    
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="5dip"
+        android:background="#70000000"
+        android:text="@string/wallpaper_instructions"
+        android:layout_alignParentTop="true"
+        android:layout_centerHorizontal="true"
+    />
+    
+    <Gallery android:id="@+id/gallery"
+        android:background="#70000000"
+        android:layout_width="fill_parent"
+        android:layout_height="60dip"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:gravity="center_vertical"
+        android:spacing="16dp"
+    />
+
+</RelativeLayout>
+   
diff --git a/samples/Home/res/values-cs/strings.xml b/samples/Home/res/values-cs/strings.xml
new file mode 100644
index 0000000..2830534
--- /dev/null
+++ b/samples/Home/res/values-cs/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="home_title">"Domů"</string>
+    <string name="show_all_apps">"Vše"</string>
+    <string name="menu_wallpaper">"Tapeta"</string>
+    <string name="menu_search">"Hledat"</string>
+    <!-- no translation found for menu_settings (1769059051084007158) -->
+    <skip />
+    <string name="wallpaper_instructions">"Klepnutím na obrázek nastavíte tapetu portrétu"</string>
+</resources>
diff --git a/samples/Home/res/values-de-rDE/strings.xml b/samples/Home/res/values-de-rDE/strings.xml
new file mode 100644
index 0000000..28a1b7c
--- /dev/null
+++ b/samples/Home/res/values-de-rDE/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="home_title">"Startseite"</string>
+    <string name="show_all_apps">"Alle"</string>
+    <string name="menu_wallpaper">"Bildschirmhintergrund"</string>
+    <string name="menu_search">"Suchen"</string>
+    <!-- no translation found for menu_settings (1769059051084007158) -->
+    <skip />
+    <string name="wallpaper_instructions">"Tippen Sie auf Bild, um Porträt-Bildschirmhintergrund einzustellen"</string>
+</resources>
diff --git a/samples/Home/res/values-es-rUS/strings.xml b/samples/Home/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..63252cc
--- /dev/null
+++ b/samples/Home/res/values-es-rUS/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="home_title">"Casa"</string>
+    <string name="show_all_apps">"Todo"</string>
+    <string name="menu_wallpaper">"Papel tapiz"</string>
+    <string name="menu_search">"Búsqueda"</string>
+    <!-- no translation found for menu_settings (1769059051084007158) -->
+    <skip />
+    <string name="wallpaper_instructions">"Puntee en la imagen para establecer papel tapiz vertical"</string>
+</resources>
diff --git a/samples/Home/res/values-land/strings.xml b/samples/Home/res/values-land/strings.xml
new file mode 100644
index 0000000..a435f41
--- /dev/null
+++ b/samples/Home/res/values-land/strings.xml
@@ -0,0 +1,21 @@
+<?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>
+    <!-- Wallpaper -->
+    <string name="wallpaper_instructions">Tap image to set landscape wallpaper</string>
+</resources>
+
diff --git a/samples/Home/res/values-nl-rNL/strings.xml b/samples/Home/res/values-nl-rNL/strings.xml
new file mode 100644
index 0000000..4a5ae4f
--- /dev/null
+++ b/samples/Home/res/values-nl-rNL/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="home_title">"Start"</string>
+    <string name="show_all_apps">"Alles"</string>
+    <string name="menu_wallpaper">"Achtergrond"</string>
+    <string name="menu_search">"Zoeken"</string>
+    <!-- no translation found for menu_settings (1769059051084007158) -->
+    <skip />
+    <string name="wallpaper_instructions">"Tik op afbeelding om portretachtergrond in te stellen"</string>
+</resources>
diff --git a/samples/Home/res/values/attrs.xml b/samples/Home/res/values/attrs.xml
new file mode 100644
index 0000000..d14e4fe
--- /dev/null
+++ b/samples/Home/res/values/attrs.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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>
+    <declare-styleable name="ApplicationsStackLayout">
+        <attr name="stackOrientation">
+            <enum name="horizontal" value="0" />
+            <enum name="vertical" value="1" />
+        </attr>
+        <attr name="marginLeft" format="dimension"  />
+        <attr name="marginTop" format="dimension"  />
+        <attr name="marginRight" format="dimension"  />
+        <attr name="marginBottom" format="dimension"  />
+    </declare-styleable>
+</resources>
diff --git a/samples/Home/res/values/strings.xml b/samples/Home/res/values/strings.xml
new file mode 100644
index 0000000..f173434
--- /dev/null
+++ b/samples/Home/res/values/strings.xml
@@ -0,0 +1,30 @@
+<?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>
+    <!-- Home -->
+    <string name="home_title">Home Sample</string>
+    <string name="show_all_apps">All</string>
+
+    <!-- Home Menus -->
+    <string name="menu_wallpaper">Wallpaper</string>
+    <string name="menu_search">Search</string>
+    <string name="menu_settings">Settings</string>
+
+    <!-- Wallpaper -->
+    <string name="wallpaper_instructions">Tap picture to set portrait wallpaper</string>
+</resources>
+
diff --git a/samples/Home/res/values/styles.xml b/samples/Home/res/values/styles.xml
new file mode 100644
index 0000000..e87aa58
--- /dev/null
+++ b/samples/Home/res/values/styles.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+    <style name="Theme" parent="android:Theme">
+        <item name="android:windowNoTitle">true</item>		
+    </style>
+</resources>
diff --git a/samples/Home/src/com/example/android/home/ApplicationInfo.java b/samples/Home/src/com/example/android/home/ApplicationInfo.java
new file mode 100644
index 0000000..79f6234
--- /dev/null
+++ b/samples/Home/src/com/example/android/home/ApplicationInfo.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.home;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Represents a launchable application. An application is made of a name (or title), an intent
+ * and an icon.
+ */
+class ApplicationInfo {
+    /**
+     * The application name.
+     */
+    CharSequence title;
+
+    /**
+     * The intent used to start the application.
+     */
+    Intent intent;
+
+    /**
+     * The application icon.
+     */
+    Drawable icon;
+
+    /**
+     * When set to true, indicates that the icon has been resized.
+     */
+    boolean filtered;
+
+    /**
+     * Creates the application intent based on a component name and various launch flags.
+     *
+     * @param className the class name of the component representing the intent
+     * @param launchFlags the launch flags
+     */
+    final void setActivity(ComponentName className, int launchFlags) {
+        intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.setComponent(className);
+        intent.setFlags(launchFlags);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ApplicationInfo)) {
+            return false;
+        }
+
+        ApplicationInfo that = (ApplicationInfo) o;
+        return title.equals(that.title) &&
+                intent.getComponent().getClassName().equals(
+                        that.intent.getComponent().getClassName());
+    }
+
+    @Override
+    public int hashCode() {
+        int result;
+        result = (title != null ? title.hashCode() : 0);
+        final String name = intent.getComponent().getClassName();
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/samples/Home/src/com/example/android/home/ApplicationsStackLayout.java b/samples/Home/src/com/example/android/home/ApplicationsStackLayout.java
new file mode 100644
index 0000000..ccc1f43
--- /dev/null
+++ b/samples/Home/src/com/example/android/home/ApplicationsStackLayout.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.home;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.TextView;
+import android.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The ApplicationsStackLayout is a specialized layout used for the purpose of the home screen
+ * only. This layout stacks various icons in three distinct areas: the recents, the favorites
+ * (or faves) and the button.
+ *
+ * This layout supports two different orientations: vertical and horizontal. When horizontal,
+ * the areas are laid out this way:
+ *
+ * [RECENTS][FAVES][BUTTON]
+ *
+ * When vertical, the layout is the following:
+ *
+ * [RECENTS]
+ * [FAVES]
+ * [BUTTON]
+ *
+ * The layout operates from the "bottom up" (or from right to left.) This means that the button
+ * area will first be laid out, then the faves area, then the recents. When there are too many
+ * favorites, the recents area is not displayed.
+ *
+ * The following attributes can be set in XML:
+ * 
+ * orientation: horizontal or vertical
+ * marginLeft: the left margin of each element in the stack
+ * marginTop: the top margin of each element in the stack
+ * marginRight: the right margin of each element in the stack
+ * marginBottom: the bottom margin of each element in the stack
+ */
+public class ApplicationsStackLayout extends ViewGroup implements View.OnClickListener {
+    public static final int HORIZONTAL = 0;
+    public static final int VERTICAL = 1;
+
+    private View mButton;
+    private LayoutInflater mInflater;
+
+    private int mFavoritesEnd;
+    private int mFavoritesStart;
+
+    private List<ApplicationInfo> mFavorites;
+    private List<ApplicationInfo> mRecents;
+
+    private int mOrientation = VERTICAL;
+
+    private int mMarginLeft;
+    private int mMarginTop;
+    private int mMarginRight;
+    private int mMarginBottom;
+
+    private Rect mDrawRect = new Rect();
+
+    private Drawable mBackground;
+    private int mIconSize;
+
+    public ApplicationsStackLayout(Context context) {
+        super(context);
+        initLayout();
+    }
+
+    public ApplicationsStackLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        TypedArray a =
+                context.obtainStyledAttributes(attrs, R.styleable.ApplicationsStackLayout);
+
+        mOrientation = a.getInt(R.styleable.ApplicationsStackLayout_stackOrientation, VERTICAL);
+
+        mMarginLeft = a.getDimensionPixelSize(R.styleable.ApplicationsStackLayout_marginLeft, 0);
+        mMarginTop = a.getDimensionPixelSize(R.styleable.ApplicationsStackLayout_marginTop, 0);
+        mMarginRight = a.getDimensionPixelSize(R.styleable.ApplicationsStackLayout_marginRight, 0);
+        mMarginBottom = a.getDimensionPixelSize(R.styleable.ApplicationsStackLayout_marginBottom, 0);
+
+        a.recycle();
+
+        mIconSize = 42; //(int) getResources().getDimension(android.R.dimen.app_icon_size);
+
+        initLayout();
+    }
+
+    private void initLayout() {
+        mInflater = LayoutInflater.from(getContext());
+        mButton = mInflater.inflate(R.layout.all_applications_button, this, false);
+        addView(mButton);
+
+        mBackground = getBackground();
+        setBackgroundDrawable(null);
+        setWillNotDraw(false);
+    }
+
+    /**
+     * Return the current orientation, either VERTICAL (default) or HORIZONTAL.
+     * 
+     * @return the stack orientation
+     */
+    public int getOrientation() {
+        return mOrientation;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        final Drawable background = mBackground;
+
+        final int right = getWidth();
+        final int bottom = getHeight();
+
+        // Draw behind recents
+        if (mOrientation == VERTICAL) {
+            mDrawRect.set(0, 0, right, mFavoritesStart);
+        } else {
+            mDrawRect.set(0, 0, mFavoritesStart, bottom);
+        }
+        background.setBounds(mDrawRect);
+        background.draw(canvas);
+
+        // Draw behind favorites
+        if (mFavoritesStart > -1) {
+            if (mOrientation == VERTICAL) {
+                mDrawRect.set(0, mFavoritesStart, right, mFavoritesEnd);
+            } else {
+                mDrawRect.set(mFavoritesStart, 0, mFavoritesEnd, bottom);
+            }
+            background.setBounds(mDrawRect);
+            background.draw(canvas);
+        }
+
+        super.onDraw(canvas);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+
+        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+        if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) {
+            throw new IllegalStateException("ApplicationsStackLayout can only be used with "
+                    + "measure spec mode=EXACTLY");
+        }
+
+        setMeasuredDimension(widthSize, heightSize);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        removeAllApplications();
+
+        LayoutParams layoutParams = mButton.getLayoutParams();
+        final int widthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
+        mButton.measure(widthSpec, heightSpec);
+
+        if (mOrientation == VERTICAL) {
+            layoutVertical();
+        } else {
+            layoutHorizontal();
+        }
+    }
+
+    private void layoutVertical() {
+        int childLeft = 0;
+        int childTop = getHeight();
+
+        int childWidth = mButton.getMeasuredWidth();
+        int childHeight = mButton.getMeasuredHeight();
+
+        childTop -= childHeight + mMarginBottom;
+        mButton.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
+        childTop -= mMarginTop;
+        mFavoritesEnd = childTop - mMarginBottom;
+
+        int oldChildTop = childTop;
+        childTop = stackApplications(mFavorites, childLeft, childTop);
+        if (childTop != oldChildTop) {
+            mFavoritesStart = childTop + mMarginTop;
+        } else {
+            mFavoritesStart = -1;
+        }
+
+        stackApplications(mRecents, childLeft, childTop);
+    }
+
+    private void layoutHorizontal() {
+        int childLeft = getWidth();
+        int childTop = 0;
+
+        int childWidth = mButton.getMeasuredWidth();
+        int childHeight = mButton.getMeasuredHeight();
+
+        childLeft -= childWidth;
+        mButton.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
+        childLeft -= mMarginLeft;
+        mFavoritesEnd = childLeft - mMarginRight;
+
+        int oldChildLeft = childLeft;
+        childLeft = stackApplications(mFavorites, childLeft, childTop);
+        if (childLeft != oldChildLeft) {
+            mFavoritesStart = childLeft + mMarginLeft;
+        } else {
+            mFavoritesStart = -1;
+        }
+
+        stackApplications(mRecents, childLeft, childTop);
+    }
+
+    private int stackApplications(List<ApplicationInfo> applications, int childLeft, int childTop) {
+        LayoutParams layoutParams;
+        int widthSpec;
+        int heightSpec;
+        int childWidth;
+        int childHeight;
+
+        final boolean isVertical = mOrientation == VERTICAL;
+
+        final int count = applications.size();
+        for (int i = count - 1; i >= 0; i--) {
+            final ApplicationInfo info = applications.get(i);
+            final View view = createApplicationIcon(mInflater, this, info);
+
+            layoutParams = view.getLayoutParams();
+            widthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY);
+            heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
+            view.measure(widthSpec, heightSpec);
+
+            childWidth = view.getMeasuredWidth();
+            childHeight = view.getMeasuredHeight();
+
+            if (isVertical) {
+                childTop -= childHeight + mMarginBottom;
+
+                if (childTop < 0) {
+                    childTop += childHeight + mMarginBottom;
+                    break;
+                }
+            } else {
+                childLeft -= childWidth + mMarginRight;
+
+                if (childLeft < 0) {
+                    childLeft += childWidth + mMarginRight;
+                    break;
+                }
+            }
+
+            addViewInLayout(view, -1, layoutParams);
+
+            view.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
+
+            if (isVertical) {
+                childTop -= mMarginTop;
+            } else {
+                childLeft -= mMarginLeft;
+            }
+        }
+
+        return isVertical ? childTop : childLeft;
+    }
+
+    private void removeAllApplications() {
+        final int count = getChildCount();
+        for (int i = count - 1; i >= 0; i--) {
+            final View view = getChildAt(i);
+            if (view != mButton) {
+                removeViewAt(i);
+            }
+        }
+    }
+
+    private View createApplicationIcon(LayoutInflater inflater,
+            ViewGroup group, ApplicationInfo info) {
+
+        TextView textView = (TextView) inflater.inflate(R.layout.favorite, group, false);
+
+        info.icon.setBounds(0, 0, mIconSize, mIconSize);
+        textView.setCompoundDrawables(null, info.icon, null, null);
+        textView.setText(info.title);
+
+        textView.setTag(info.intent);
+        textView.setOnClickListener(this);
+
+        return textView;
+    }
+
+    /**
+     * Sets the list of favorites.
+     *
+     * @param applications the applications to put in the favorites area
+     */
+    public void setFavorites(List<ApplicationInfo> applications) {
+        mFavorites = applications;
+        requestLayout();
+    }
+
+    /**
+     * Sets the list of recents.
+     *
+     * @param applications the applications to put in the recents area
+     */
+    public void setRecents(List<ApplicationInfo> applications) {
+        mRecents = applications;
+        requestLayout();
+    }
+
+    public void onClick(View v) {
+        getContext().startActivity((Intent) v.getTag());
+    }
+}
diff --git a/samples/Home/src/com/example/android/home/Home.java b/samples/Home/src/com/example/android/home/Home.java
new file mode 100644
index 0000000..7e94cc3
--- /dev/null
+++ b/samples/Home/src/com/example/android/home/Home.java
@@ -0,0 +1,743 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.home;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.SearchManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.ColorFilter;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.PaintDrawable;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.util.Xml;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.animation.LayoutAnimationController;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.io.FileReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class Home extends Activity {
+    /**
+     * Tag used for logging errors.
+     */
+    private static final String LOG_TAG = "Home";
+
+    /**
+     * Keys during freeze/thaw.
+     */
+    private static final String KEY_SAVE_GRID_OPENED = "grid.opened";
+
+    private static final String DEFAULT_FAVORITES_PATH = "etc/favorites.xml";
+
+    private static final String TAG_FAVORITES = "favorites";
+    private static final String TAG_FAVORITE = "favorite";
+    private static final String TAG_PACKAGE = "package";
+    private static final String TAG_CLASS = "class";    
+
+    // Identifiers for option menu items
+    private static final int MENU_WALLPAPER_SETTINGS = Menu.FIRST + 1;
+    private static final int MENU_SEARCH = MENU_WALLPAPER_SETTINGS + 1;
+    private static final int MENU_SETTINGS = MENU_SEARCH + 1;
+
+    /**
+     * Maximum number of recent tasks to query.
+     */
+    private static final int MAX_RECENT_TASKS = 20;
+
+    private static boolean mWallpaperChecked;
+    private static ArrayList<ApplicationInfo> mApplications;
+    private static LinkedList<ApplicationInfo> mFavorites;
+
+    private final BroadcastReceiver mWallpaperReceiver = new WallpaperIntentReceiver();
+    private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
+
+    private GridView mGrid;
+
+    private LayoutAnimationController mShowLayoutAnimation;
+    private LayoutAnimationController mHideLayoutAnimation;
+
+    private boolean mBlockAnimation;
+
+    private View mShowApplications;
+    private CheckBox mShowApplicationsCheck;
+
+    private ApplicationsStackLayout mApplicationsStack;
+
+    private Animation mGridEntry;
+    private Animation mGridExit;
+    
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
+
+        setContentView(R.layout.home);
+
+        registerIntentReceivers();
+
+        setDefaultWallpaper();
+
+        loadApplications(true);
+
+        bindApplications();
+        bindFavorites(true);
+        bindRecents();
+        bindButtons();
+
+        mGridEntry = AnimationUtils.loadAnimation(this, R.anim.grid_entry);
+        mGridExit = AnimationUtils.loadAnimation(this, R.anim.grid_exit);
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+
+        // Close the menu
+        if (Intent.ACTION_MAIN.equals(intent.getAction())) {
+            getWindow().closeAllPanels();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        // Remove the callback for the cached drawables or we leak
+        // the previous Home screen on orientation change
+        final int count = mApplications.size();
+        for (int i = 0; i < count; i++) {
+            mApplications.get(i).icon.setCallback(null);
+        }
+
+        unregisterReceiver(mWallpaperReceiver);
+        unregisterReceiver(mApplicationsReceiver);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        bindRecents();
+    }
+    
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+        final boolean opened = state.getBoolean(KEY_SAVE_GRID_OPENED, false);
+        if (opened) {
+            showApplications(false);
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(KEY_SAVE_GRID_OPENED, mGrid.getVisibility() == View.VISIBLE);
+    }
+
+    /**
+     * Registers various intent receivers. The current implementation registers
+     * only a wallpaper intent receiver to let other applications change the
+     * wallpaper.
+     */
+    private void registerIntentReceivers() {
+        IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
+        registerReceiver(mWallpaperReceiver, filter);
+
+        filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addDataScheme("package");
+        registerReceiver(mApplicationsReceiver, filter);
+    }
+
+    /**
+     * Creates a new appplications adapter for the grid view and registers it.
+     */
+    private void bindApplications() {
+        if (mGrid == null) {
+            mGrid = (GridView) findViewById(R.id.all_apps);
+        }
+        mGrid.setAdapter(new ApplicationsAdapter(this, mApplications));
+        mGrid.setSelection(0);
+
+        if (mApplicationsStack == null) {
+            mApplicationsStack = (ApplicationsStackLayout) findViewById(R.id.faves_and_recents);
+        }
+    }
+
+    /**
+     * Binds actions to the various buttons.
+     */
+    private void bindButtons() {
+        mShowApplications = findViewById(R.id.show_all_apps);
+        mShowApplications.setOnClickListener(new ShowApplications());
+        mShowApplicationsCheck = (CheckBox) findViewById(R.id.show_all_apps_check);
+
+        mGrid.setOnItemClickListener(new ApplicationLauncher());
+    }
+
+    /**
+     * When no wallpaper was manually set, a default wallpaper is used instead.
+     */
+    private void setDefaultWallpaper() {
+        if (!mWallpaperChecked) {
+            Drawable wallpaper = peekWallpaper();
+            if (wallpaper == null) {
+                try {
+                    clearWallpaper();
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "Failed to clear wallpaper " + e);
+                }
+            } else {
+                getWindow().setBackgroundDrawable(new ClippedDrawable(wallpaper));
+            }
+            mWallpaperChecked = true;
+        }
+    }
+
+    /**
+     * Refreshes the favorite applications stacked over the all apps button.
+     * The number of favorites depends on the user.
+     */
+    private void bindFavorites(boolean isLaunching) {
+        if (!isLaunching || mFavorites == null) {
+
+            FileReader favReader;
+
+            // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
+            final File favFile = new File(Environment.getRootDirectory(), DEFAULT_FAVORITES_PATH);
+            try {
+                favReader = new FileReader(favFile);
+            } catch (FileNotFoundException e) {
+                Log.e(LOG_TAG, "Couldn't find or open favorites file " + favFile);
+                return;
+            }
+
+            if (mFavorites == null) {
+                mFavorites = new LinkedList<ApplicationInfo>();
+            } else {
+                mFavorites.clear();
+            }
+
+            final Intent intent = new Intent(Intent.ACTION_MAIN, null);
+            intent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+            final PackageManager packageManager = getPackageManager();
+
+            try {
+                final XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(favReader);
+
+                beginDocument(parser, TAG_FAVORITES);
+
+                ApplicationInfo info;
+
+                while (true) {
+                    nextElement(parser);
+
+                    String name = parser.getName();
+                    if (!TAG_FAVORITE.equals(name)) {
+                        break;
+                    }
+
+                    final String favoritePackage = parser.getAttributeValue(null, TAG_PACKAGE);
+                    final String favoriteClass = parser.getAttributeValue(null, TAG_CLASS);
+
+                    final ComponentName cn = new ComponentName(favoritePackage, favoriteClass);
+                    intent.setComponent(cn);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+                    info = getApplicationInfo(packageManager, intent);
+                    if (info != null) {
+                        info.intent = intent;
+                        mFavorites.addFirst(info);
+                    }
+                }
+            } catch (XmlPullParserException e) {
+                Log.w(LOG_TAG, "Got exception parsing favorites.", e);
+            } catch (IOException e) {
+                Log.w(LOG_TAG, "Got exception parsing favorites.", e);
+            }
+        }
+
+        mApplicationsStack.setFavorites(mFavorites);
+    }
+
+    private static void beginDocument(XmlPullParser parser, String firstElementName)
+            throws XmlPullParserException, IOException {
+
+        int type;
+        while ((type = parser.next()) != XmlPullParser.START_TAG &&
+                type != XmlPullParser.END_DOCUMENT) {
+            // Empty
+        }
+
+        if (type != XmlPullParser.START_TAG) {
+            throw new XmlPullParserException("No start tag found");
+        }
+
+        if (!parser.getName().equals(firstElementName)) {
+            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
+                    ", expected " + firstElementName);
+        }
+    }
+
+    private static void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException {
+        int type;
+        while ((type = parser.next()) != XmlPullParser.START_TAG &&
+                type != XmlPullParser.END_DOCUMENT) {
+            // Empty
+        }
+    }
+
+    /**
+     * Refreshes the recently launched applications stacked over the favorites. The number
+     * of recents depends on how many favorites are present.
+     */
+    private void bindRecents() {
+        final PackageManager manager = getPackageManager();
+        final ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
+        final List<ActivityManager.RecentTaskInfo> recentTasks = tasksManager.getRecentTasks(
+                MAX_RECENT_TASKS, 0);
+
+        final int count = recentTasks.size();
+        final ArrayList<ApplicationInfo> recents = new ArrayList<ApplicationInfo>();
+
+        for (int i = count - 1; i >= 0; i--) {
+            final Intent intent = recentTasks.get(i).baseIntent;
+
+            if (Intent.ACTION_MAIN.equals(intent.getAction()) &&
+                    !intent.hasCategory(Intent.CATEGORY_HOME)) {
+
+                ApplicationInfo info = getApplicationInfo(manager, intent);
+                if (info != null) {
+                    info.intent = intent;
+                    if (!mFavorites.contains(info)) {
+                        recents.add(info);
+                    }
+                }
+            }
+        }
+
+        mApplicationsStack.setRecents(recents);
+    }
+
+    private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent) {
+        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
+
+        if (resolveInfo == null) {
+            return null;
+        }
+
+        final ApplicationInfo info = new ApplicationInfo();
+        final ActivityInfo activityInfo = resolveInfo.activityInfo;
+        info.icon = activityInfo.loadIcon(manager);
+        if (info.title == null || info.title.length() == 0) {
+            info.title = activityInfo.loadLabel(manager);
+        }
+        if (info.title == null) {
+            info.title = "";
+        }
+        return info;
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (event.getKeyCode()) {
+                case KeyEvent.KEYCODE_BACK:
+                    return true;
+                case KeyEvent.KEYCODE_HOME:
+                    return true;
+            }
+        }
+
+        return super.dispatchKeyEvent(event);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        menu.add(0, MENU_WALLPAPER_SETTINGS, 0, R.string.menu_wallpaper)
+                 .setIcon(android.R.drawable.ic_menu_gallery)
+                 .setAlphabeticShortcut('W');
+        menu.add(0, MENU_SEARCH, 0, R.string.menu_search)
+                .setIcon(android.R.drawable.ic_search_category_default)
+                .setAlphabeticShortcut(SearchManager.MENU_KEY);
+        menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings)
+                .setIcon(android.R.drawable.ic_menu_preferences)
+                .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_WALLPAPER_SETTINGS:
+                startWallpaper();
+                return true;
+            case MENU_SEARCH:
+                onSearchRequested();
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void startWallpaper() {
+        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
+        startActivity(Intent.createChooser(pickWallpaper, getString(R.string.menu_wallpaper)));
+    }
+
+    /**
+     * Loads the list of installed applications in mApplications.
+     */
+    private void loadApplications(boolean isLaunching) {
+        if (isLaunching && mApplications != null) {
+            return;
+        }
+
+        PackageManager manager = getPackageManager();
+
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+        final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
+        Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));
+
+        if (apps != null) {
+            final int count = apps.size();
+
+            if (mApplications == null) {
+                mApplications = new ArrayList<ApplicationInfo>(count);
+            }
+            mApplications.clear();
+
+            for (int i = 0; i < count; i++) {
+                ApplicationInfo application = new ApplicationInfo();
+                ResolveInfo info = apps.get(i);
+
+                application.title = info.loadLabel(manager);
+                application.setActivity(new ComponentName(
+                        info.activityInfo.applicationInfo.packageName,
+                        info.activityInfo.name),
+                        Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                application.icon = info.activityInfo.loadIcon(manager);
+
+                mApplications.add(application);
+            }
+        }
+    }
+
+    /**
+     * Shows all of the applications by playing an animation on the grid.
+     */
+    private void showApplications(boolean animate) {
+        if (mBlockAnimation) {
+            return;
+        }
+        mBlockAnimation = true;
+
+        mShowApplicationsCheck.toggle();
+
+        if (mShowLayoutAnimation == null) {
+            mShowLayoutAnimation = AnimationUtils.loadLayoutAnimation(
+                    this, R.anim.show_applications);
+        }
+
+        // This enables a layout animation; if you uncomment this code, you need to
+        // comment the line mGrid.startAnimation() below
+//        mGrid.setLayoutAnimationListener(new ShowGrid());
+//        mGrid.setLayoutAnimation(mShowLayoutAnimation);
+//        mGrid.startLayoutAnimation();
+
+        if (animate) {
+            mGridEntry.setAnimationListener(new ShowGrid());
+            mGrid.startAnimation(mGridEntry);
+        }
+
+        mGrid.setVisibility(View.VISIBLE);
+
+        if (!animate) {
+            mBlockAnimation = false;
+        }
+
+        // ViewDebug.startHierarchyTracing("Home", mGrid);
+    }
+
+    /**
+     * Hides all of the applications by playing an animation on the grid.
+     */
+    private void hideApplications() {
+        if (mBlockAnimation) {
+            return;
+        }
+        mBlockAnimation = true;
+
+        mShowApplicationsCheck.toggle();
+
+        if (mHideLayoutAnimation == null) {
+            mHideLayoutAnimation = AnimationUtils.loadLayoutAnimation(
+                    this, R.anim.hide_applications);
+        }
+
+        mGridExit.setAnimationListener(new HideGrid());
+        mGrid.startAnimation(mGridExit);
+        mGrid.setVisibility(View.INVISIBLE);
+        mShowApplications.requestFocus();
+
+        // This enables a layout animation; if you uncomment this code, you need to
+        // comment the line mGrid.startAnimation() above
+//        mGrid.setLayoutAnimationListener(new HideGrid());
+//        mGrid.setLayoutAnimation(mHideLayoutAnimation);
+//        mGrid.startLayoutAnimation();
+    }
+
+    /**
+     * Receives intents from other applications to change the wallpaper.
+     */
+    private class WallpaperIntentReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            getWindow().setBackgroundDrawable(new ClippedDrawable(getWallpaper()));
+        }
+    }
+
+    /**
+     * Receives notifications when applications are added/removed.
+     */
+    private class ApplicationsIntentReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            loadApplications(false);
+            bindApplications();
+            bindRecents();
+            bindFavorites(false);
+        }
+    }
+
+    /**
+     * GridView adapter to show the list of all installed applications.
+     */
+    private class ApplicationsAdapter extends ArrayAdapter<ApplicationInfo> {
+        private Rect mOldBounds = new Rect();
+
+        public ApplicationsAdapter(Context context, ArrayList<ApplicationInfo> apps) {
+            super(context, 0, apps);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final ApplicationInfo info = mApplications.get(position);
+
+            if (convertView == null) {
+                final LayoutInflater inflater = getLayoutInflater();
+                convertView = inflater.inflate(R.layout.application, parent, false);
+            }
+
+            Drawable icon = info.icon;
+
+            if (!info.filtered) {
+                //final Resources resources = getContext().getResources();
+                int width = 42;//(int) resources.getDimension(android.R.dimen.app_icon_size);
+                int height = 42;//(int) resources.getDimension(android.R.dimen.app_icon_size);
+
+                final int iconWidth = icon.getIntrinsicWidth();
+                final int iconHeight = icon.getIntrinsicHeight();
+
+                if (icon instanceof PaintDrawable) {
+                    PaintDrawable painter = (PaintDrawable) icon;
+                    painter.setIntrinsicWidth(width);
+                    painter.setIntrinsicHeight(height);
+                }
+
+                if (width > 0 && height > 0 && (width < iconWidth || height < iconHeight)) {
+                    final float ratio = (float) iconWidth / iconHeight;
+
+                    if (iconWidth > iconHeight) {
+                        height = (int) (width / ratio);
+                    } else if (iconHeight > iconWidth) {
+                        width = (int) (height * ratio);
+                    }
+
+                    final Bitmap.Config c =
+                            icon.getOpacity() != PixelFormat.OPAQUE ?
+                                Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
+                    final Bitmap thumb = Bitmap.createBitmap(width, height, c);
+                    final Canvas canvas = new Canvas(thumb);
+                    canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 0));
+                    // Copy the old bounds to restore them later
+                    // If we were to do oldBounds = icon.getBounds(),
+                    // the call to setBounds() that follows would
+                    // change the same instance and we would lose the
+                    // old bounds
+                    mOldBounds.set(icon.getBounds());
+                    icon.setBounds(0, 0, width, height);
+                    icon.draw(canvas);
+                    icon.setBounds(mOldBounds);
+                    icon = info.icon = new BitmapDrawable(thumb);
+                    info.filtered = true;
+                }
+            }
+
+            final TextView textView = (TextView) convertView.findViewById(R.id.label);
+            textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
+            textView.setText(info.title);
+
+            return convertView;
+        }
+    }
+
+    /**
+     * Shows and hides the applications grid view.
+     */
+    private class ShowApplications implements View.OnClickListener {
+        public void onClick(View v) {
+            if (mGrid.getVisibility() != View.VISIBLE) {
+                showApplications(true);
+            } else {
+                hideApplications();
+            }
+        }
+    }
+
+    /**
+     * Hides the applications grid when the layout animation is over.
+     */
+    private class HideGrid implements Animation.AnimationListener {
+        public void onAnimationStart(Animation animation) {
+        }
+
+        public void onAnimationEnd(Animation animation) {
+            mBlockAnimation = false;
+        }
+
+        public void onAnimationRepeat(Animation animation) {
+        }
+    }
+
+    /**
+     * Shows the applications grid when the layout animation is over.
+     */
+    private class ShowGrid implements Animation.AnimationListener {
+        public void onAnimationStart(Animation animation) {
+        }
+
+        public void onAnimationEnd(Animation animation) {
+            mBlockAnimation = false;
+            // ViewDebug.stopHierarchyTracing();
+        }
+
+        public void onAnimationRepeat(Animation animation) {
+        }
+    }
+
+    /**
+     * Starts the selected activity/application in the grid view.
+     */
+    private class ApplicationLauncher implements AdapterView.OnItemClickListener {
+        public void onItemClick(AdapterView parent, View v, int position, long id) {
+            ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
+            startActivity(app.intent);
+        }
+    }
+
+    /**
+     * When a drawable is attached to a View, the View gives the Drawable its dimensions
+     * by calling Drawable.setBounds(). In this application, the View that draws the
+     * wallpaper has the same size as the screen. However, the wallpaper might be larger
+     * that the screen which means it will be automatically stretched. Because stretching
+     * a bitmap while drawing it is very expensive, we use a ClippedDrawable instead.
+     * This drawable simply draws another wallpaper but makes sure it is not stretched
+     * by always giving it its intrinsic dimensions. If the wallpaper is larger than the
+     * screen, it will simply get clipped but it won't impact performance.
+     */
+    private class ClippedDrawable extends Drawable {
+        private final Drawable mWallpaper;
+
+        public ClippedDrawable(Drawable wallpaper) {
+            mWallpaper = wallpaper;
+        }
+
+        @Override
+        public void setBounds(int left, int top, int right, int bottom) {
+            super.setBounds(left, top, right, bottom);
+            // Ensure the wallpaper is as large as it really is, to avoid stretching it
+            // at drawing time
+            mWallpaper.setBounds(left, top, left + mWallpaper.getIntrinsicWidth(),
+                    top + mWallpaper.getIntrinsicHeight());
+        }
+
+        public void draw(Canvas canvas) {
+            mWallpaper.draw(canvas);
+        }
+
+        public void setAlpha(int alpha) {
+            mWallpaper.setAlpha(alpha);
+        }
+
+        public void setColorFilter(ColorFilter cf) {
+            mWallpaper.setColorFilter(cf);
+        }
+
+        public int getOpacity() {
+            return mWallpaper.getOpacity();
+        }
+    }
+}
diff --git a/samples/Home/src/com/example/android/home/Wallpaper.java b/samples/Home/src/com/example/android/home/Wallpaper.java
new file mode 100644
index 0000000..3401c49
--- /dev/null
+++ b/samples/Home/src/com/example/android/home/Wallpaper.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2006 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.home;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.Gallery;
+import android.widget.ImageView;
+import android.widget.Gallery.LayoutParams;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Wallpaper picker for the Home application. User can choose from
+ * a gallery of stock photos.
+ */
+public class Wallpaper extends Activity implements
+        AdapterView.OnItemSelectedListener, AdapterView.OnItemClickListener {
+    
+    private static final String LOG_TAG = "Home";
+
+    private static final Integer[] THUMB_IDS = {
+            R.drawable.bg_android_icon,
+            R.drawable.bg_sunrise_icon,
+            R.drawable.bg_sunset_icon,
+    };
+
+    private static final Integer[] IMAGE_IDS = {
+            R.drawable.bg_android,
+            R.drawable.bg_sunrise,
+            R.drawable.bg_sunset,
+    };
+
+    private Gallery mGallery;
+    private boolean mIsWallpaperSet;
+        
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        setContentView(R.layout.wallpaper);
+
+        mGallery = (Gallery) findViewById(R.id.gallery);
+        mGallery.setAdapter(new ImageAdapter(this));
+        mGallery.setOnItemSelectedListener(this);
+        mGallery.setOnItemClickListener(this);
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mIsWallpaperSet = false;
+    }
+
+    public void onItemSelected(AdapterView parent, View v, int position, long id) {
+        getWindow().setBackgroundDrawableResource(IMAGE_IDS[position]);
+    }
+    
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        selectWallpaper(position);
+    }
+
+    /*
+     * When using touch if you tap an image it triggers both the onItemClick and
+     * the onTouchEvent causing the wallpaper to be set twice. Synchronize this
+     * method and ensure we only set the wallpaper once.
+     */
+    private synchronized void selectWallpaper(int position) {
+        if (mIsWallpaperSet) {
+            return;
+        }
+        mIsWallpaperSet = true;
+        try {
+            InputStream stream = getResources().openRawResource(IMAGE_IDS[position]);
+            setWallpaper(stream);
+            setResult(RESULT_OK);
+            finish();
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Failed to set wallpaper " + e);
+        }
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+    }
+    
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        selectWallpaper(mGallery.getSelectedItemPosition());
+        return true;
+    }
+
+    public class ImageAdapter extends BaseAdapter {
+
+        private Context mContext;
+        
+        public ImageAdapter(Context c) {
+            mContext = c;
+        }
+
+        public int getCount() {
+            return THUMB_IDS.length;
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(final int position, View convertView, ViewGroup parent) {
+            ImageView i = new ImageView(mContext);
+
+            i.setImageResource(THUMB_IDS[position]);
+            i.setAdjustViewBounds(true);
+            i.setLayoutParams(new Gallery.LayoutParams(
+                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+            i.setBackgroundResource(android.R.drawable.picture_frame);
+            return i;
+        }
+
+    }
+
+}
+
+    
diff --git a/samples/LunarLander/Android.mk b/samples/LunarLander/Android.mk
new file mode 100644
index 0000000..8aa11c8
--- /dev/null
+++ b/samples/LunarLander/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 := LunarLander
+
+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/LunarLander/AndroidManifest.xml b/samples/LunarLander/AndroidManifest.xml
new file mode 100644
index 0000000..7fdc572
--- /dev/null
+++ b/samples/LunarLander/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.lunarlander">
+    <application android:icon="@drawable/app_lunar_lander" android:label="@string/app_name">
+        <activity android:name="LunarLander">
+            <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/LunarLander/_index.html b/samples/LunarLander/_index.html
new file mode 100644
index 0000000..02daeef
--- /dev/null
+++ b/samples/LunarLander/_index.html
@@ -0,0 +1,12 @@
+<p>A sample game.  Your objective: to land on the moon.
+It demonstrates...
+<ul> 
+<li>loading and drawing resources
+<li>taking keystrokes
+<li>animating by calling invalidate() from draw()
+<li>handling onPause() in an animation
+<li>and many other goodies...
+</ul>
+</p>
+
+<img height="220px" width="320px" alt="Lunar Lander Example" class="gallery"  src="sample_lunarlander.png" >
\ No newline at end of file
diff --git a/samples/LunarLander/res/drawable-land/earthrise.png b/samples/LunarLander/res/drawable-land/earthrise.png
new file mode 100644
index 0000000..e2ecdc5
--- /dev/null
+++ b/samples/LunarLander/res/drawable-land/earthrise.png
Binary files differ
diff --git a/samples/LunarLander/res/drawable-port/earthrise.png b/samples/LunarLander/res/drawable-port/earthrise.png
new file mode 100644
index 0000000..a13836c
--- /dev/null
+++ b/samples/LunarLander/res/drawable-port/earthrise.png
Binary files differ
diff --git a/samples/LunarLander/res/drawable/app_lunar_lander.png b/samples/LunarLander/res/drawable/app_lunar_lander.png
new file mode 100644
index 0000000..7557b8c
--- /dev/null
+++ b/samples/LunarLander/res/drawable/app_lunar_lander.png
Binary files differ
diff --git a/samples/LunarLander/res/drawable/lander_crashed.png b/samples/LunarLander/res/drawable/lander_crashed.png
new file mode 100644
index 0000000..a73c015
--- /dev/null
+++ b/samples/LunarLander/res/drawable/lander_crashed.png
Binary files differ
diff --git a/samples/LunarLander/res/drawable/lander_firing.png b/samples/LunarLander/res/drawable/lander_firing.png
new file mode 100644
index 0000000..91378de
--- /dev/null
+++ b/samples/LunarLander/res/drawable/lander_firing.png
Binary files differ
diff --git a/samples/LunarLander/res/drawable/lander_plain.png b/samples/LunarLander/res/drawable/lander_plain.png
new file mode 100644
index 0000000..da448e4
--- /dev/null
+++ b/samples/LunarLander/res/drawable/lander_plain.png
Binary files differ
diff --git a/samples/LunarLander/res/layout/lunar_layout.xml b/samples/LunarLander/res/layout/lunar_layout.xml
new file mode 100644
index 0000000..9ad0536
--- /dev/null
+++ b/samples/LunarLander/res/layout/lunar_layout.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    
+    <com.example.android.lunarlander.LunarView
+      android:id="@+id/lunar"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"/>
+    
+    <RelativeLayout
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" >
+        <TextView
+          android:id="@+id/text"
+		  android:text="@string/lunar_layout_text_text"
+		  android:visibility="visible"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_centerInParent="true"
+          android:gravity="center_horizontal"
+          android:textColor="#88ffffff"
+          android:textSize="24sp"/>
+     </RelativeLayout>
+         
+</FrameLayout>
diff --git a/samples/LunarLander/res/values/strings.xml b/samples/LunarLander/res/values/strings.xml
new file mode 100644
index 0000000..ac81847
--- /dev/null
+++ b/samples/LunarLander/res/values/strings.xml
@@ -0,0 +1,40 @@
+<?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>
+	<string name="app_name">Lunar Lander</string>
+	
+    <string name="menu_start">Start</string>
+    <string name="menu_stop">Stop</string>
+    <string name="menu_pause">Pause</string>
+    <string name="menu_resume">Resume</string>
+    <string name="menu_easy">Easy</string>
+    <string name="menu_medium">Medium</string>
+    <string name="menu_hard">Hard</string>
+    
+    <string name="mode_ready">Lunar Lander\nPress Up To Play</string>
+	<string name="mode_pause">Paused\nPress Up To Resume</string>
+	<string name="mode_lose">Game Over\nPress Up To Play</string>
+	<string name="mode_win_prefix">Success!\n</string> 
+	<string name="mode_win_suffix">in a row\nPress Up to Play</string> 
+	
+	<string name="message_stopped">Stopped</string>
+	<string name="message_off_pad">Off Landing Pad</string> 
+	<string name="message_too_fast">Too Fast</string> 
+	<string name="message_bad_angle">Bad Angle</string> 
+
+    <string name="lunar_layout_text_text"></string>
+</resources>
diff --git a/samples/LunarLander/sample_lunarlander.png b/samples/LunarLander/sample_lunarlander.png
new file mode 100644
index 0000000..ea1ef14
--- /dev/null
+++ b/samples/LunarLander/sample_lunarlander.png
Binary files differ
diff --git a/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java b/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
new file mode 100644
index 0000000..7f54ff6
--- /dev/null
+++ b/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.lunarlander;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.Window;
+import android.widget.TextView;
+
+import com.example.android.lunarlander.LunarView.LunarThread;
+
+/**
+ * This is a simple LunarLander activity that houses a single LunarView. It
+ * demonstrates...
+ * <ul>
+ * <li>animating by calling invalidate() from draw()
+ * <li>loading and drawing resources
+ * <li>handling onPause() in an animation
+ * </ul>
+ */
+public class LunarLander extends Activity {
+    private static final int MENU_EASY = 1;
+
+    private static final int MENU_HARD = 2;
+
+    private static final int MENU_MEDIUM = 3;
+
+    private static final int MENU_PAUSE = 4;
+
+    private static final int MENU_RESUME = 5;
+
+    private static final int MENU_START = 6;
+
+    private static final int MENU_STOP = 7;
+
+    /** A handle to the thread that's actually running the animation. */
+    private LunarThread mLunarThread;
+
+    /** A handle to the View in which the game is running. */
+    private LunarView mLunarView;
+
+    /**
+     * Invoked during init to give the Activity a chance to set up its Menu.
+     * 
+     * @param menu the Menu to which entries may be added
+     * @return true
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        menu.add(0, MENU_START, 0, R.string.menu_start);
+        menu.add(0, MENU_STOP, 0, R.string.menu_stop);
+        menu.add(0, MENU_PAUSE, 0, R.string.menu_pause);
+        menu.add(0, MENU_RESUME, 0, R.string.menu_resume);
+        menu.add(0, MENU_EASY, 0, R.string.menu_easy);
+        menu.add(0, MENU_MEDIUM, 0, R.string.menu_medium);
+        menu.add(0, MENU_HARD, 0, R.string.menu_hard);
+
+        return true;
+    }
+
+    /**
+     * Invoked when the user selects an item from the Menu.
+     * 
+     * @param item the Menu entry which was selected
+     * @return true if the Menu item was legit (and we consumed it), false
+     *         otherwise
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_START:
+                mLunarThread.doStart();
+                return true;
+            case MENU_STOP:
+                mLunarThread.setState(LunarThread.STATE_LOSE,
+                        getText(R.string.message_stopped));
+                return true;
+            case MENU_PAUSE:
+                mLunarThread.pause();
+                return true;
+            case MENU_RESUME:
+                mLunarThread.unpause();
+                return true;
+            case MENU_EASY:
+                mLunarThread.setDifficulty(LunarThread.DIFFICULTY_EASY);
+                return true;
+            case MENU_MEDIUM:
+                mLunarThread.setDifficulty(LunarThread.DIFFICULTY_MEDIUM);
+                return true;
+            case MENU_HARD:
+                mLunarThread.setDifficulty(LunarThread.DIFFICULTY_HARD);
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Invoked when the Activity is created.
+     * 
+     * @param savedInstanceState a Bundle containing state saved from a previous
+     *        execution, or null if this is a new execution
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // turn off the window's title bar
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        // tell system to use the layout defined in our XML file
+        setContentView(R.layout.lunar_layout);
+
+        // get handles to the LunarView from XML, and its LunarThread
+        mLunarView = (LunarView) findViewById(R.id.lunar);
+        mLunarThread = mLunarView.getThread();
+
+        // give the LunarView a handle to the TextView used for messages
+        mLunarView.setTextView((TextView) findViewById(R.id.text));
+
+        if (savedInstanceState == null) {
+            // we were just launched: set up a new game
+            mLunarThread.setState(LunarThread.STATE_READY);
+            Log.w(this.getClass().getName(), "SIS is null");
+        } else {
+            // we are being restored: resume a previous game
+            mLunarThread.restoreState(savedInstanceState);
+            Log.w(this.getClass().getName(), "SIS is nonnull");
+        }
+    }
+
+    /**
+     * Invoked when the Activity loses user focus.
+     */
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mLunarView.getThread().pause(); // pause game when Activity pauses
+    }
+
+    /**
+     * Notification that something is about to happen, to give the Activity a
+     * chance to save state.
+     * 
+     * @param outState a Bundle into which this Activity should save its state
+     */
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        // just have the View's thread save its state into our Bundle
+        super.onSaveInstanceState(outState);
+        mLunarThread.saveState(outState);
+        Log.w(this.getClass().getName(), "SIS called");
+    }
+}
diff --git a/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java b/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
new file mode 100644
index 0000000..c52c7ab
--- /dev/null
+++ b/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
@@ -0,0 +1,885 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.lunarlander;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.TextView;
+
+
+/**
+ * View that draws, takes keystrokes, etc. for a simple LunarLander game.
+ * 
+ * Has a mode which RUNNING, PAUSED, etc. Has a x, y, dx, dy, ... capturing the
+ * current ship physics. All x/y etc. are measured with (0,0) at the lower left.
+ * updatePhysics() advances the physics based on realtime. draw() renders the
+ * ship, and does an invalidate() to prompt another draw() as soon as possible
+ * by the system.
+ */
+class LunarView extends SurfaceView implements SurfaceHolder.Callback {
+    class LunarThread extends Thread {
+        /*
+         * Difficulty setting constants
+         */
+        public static final int DIFFICULTY_EASY = 0;
+        public static final int DIFFICULTY_HARD = 1;
+        public static final int DIFFICULTY_MEDIUM = 2;
+        /*
+         * Physics constants
+         */
+        public static final int PHYS_DOWN_ACCEL_SEC = 35;
+        public static final int PHYS_FIRE_ACCEL_SEC = 80;
+        public static final int PHYS_FUEL_INIT = 60;
+        public static final int PHYS_FUEL_MAX = 100;
+        public static final int PHYS_FUEL_SEC = 10;
+        public static final int PHYS_SLEW_SEC = 120; // degrees/second rotate
+        public static final int PHYS_SPEED_HYPERSPACE = 180;
+        public static final int PHYS_SPEED_INIT = 30;
+        public static final int PHYS_SPEED_MAX = 120;
+        /*
+         * State-tracking constants
+         */
+        public static final int STATE_LOSE = 1;
+        public static final int STATE_PAUSE = 2;
+        public static final int STATE_READY = 3;
+        public static final int STATE_RUNNING = 4;
+        public static final int STATE_WIN = 5;
+
+        /*
+         * Goal condition constants
+         */
+        public static final int TARGET_ANGLE = 18; // > this angle means crash
+        public static final int TARGET_BOTTOM_PADDING = 17; // px below gear
+        public static final int TARGET_PAD_HEIGHT = 8; // how high above ground
+        public static final int TARGET_SPEED = 28; // > this speed means crash
+        public static final double TARGET_WIDTH = 1.6; // width of target
+        /*
+         * UI constants (i.e. the speed & fuel bars)
+         */
+        public static final int UI_BAR = 100; // width of the bar(s)
+        public static final int UI_BAR_HEIGHT = 10; // height of the bar(s)
+        private static final String KEY_DIFFICULTY = "mDifficulty";
+        private static final String KEY_DX = "mDX";
+
+        private static final String KEY_DY = "mDY";
+        private static final String KEY_FUEL = "mFuel";
+        private static final String KEY_GOAL_ANGLE = "mGoalAngle";
+        private static final String KEY_GOAL_SPEED = "mGoalSpeed";
+        private static final String KEY_GOAL_WIDTH = "mGoalWidth";
+
+        private static final String KEY_GOAL_X = "mGoalX";
+        private static final String KEY_HEADING = "mHeading";
+        private static final String KEY_LANDER_HEIGHT = "mLanderHeight";
+        private static final String KEY_LANDER_WIDTH = "mLanderWidth";
+        private static final String KEY_WINS = "mWinsInARow";
+
+        private static final String KEY_X = "mX";
+        private static final String KEY_Y = "mY";
+
+        /*
+         * Member (state) fields
+         */
+        /** The drawable to use as the background of the animation canvas */
+        private Bitmap mBackgroundImage;
+
+        /**
+         * Current height of the surface/canvas.
+         * 
+         * @see #setSurfaceSize
+         */
+        private int mCanvasHeight = 1;
+
+        /**
+         * Current width of the surface/canvas.
+         * 
+         * @see #setSurfaceSize
+         */
+        private int mCanvasWidth = 1;
+
+        /** What to draw for the Lander when it has crashed */
+        private Drawable mCrashedImage;
+
+        /**
+         * Current difficulty -- amount of fuel, allowed angle, etc. Default is
+         * MEDIUM.
+         */
+        private int mDifficulty;
+
+        /** Velocity dx. */
+        private double mDX;
+
+        /** Velocity dy. */
+        private double mDY;
+
+        /** Is the engine burning? */
+        private boolean mEngineFiring;
+
+        /** What to draw for the Lander when the engine is firing */
+        private Drawable mFiringImage;
+
+        /** Fuel remaining */
+        private double mFuel;
+
+        /** Allowed angle. */
+        private int mGoalAngle;
+
+        /** Allowed speed. */
+        private int mGoalSpeed;
+
+        /** Width of the landing pad. */
+        private int mGoalWidth;
+
+        /** X of the landing pad. */
+        private int mGoalX;
+
+        /** Message handler used by thread to interact with TextView */
+        private Handler mHandler;
+
+        /**
+         * Lander heading in degrees, with 0 up, 90 right. Kept in the range
+         * 0..360.
+         */
+        private double mHeading;
+
+        /** Pixel height of lander image. */
+        private int mLanderHeight;
+
+        /** What to draw for the Lander in its normal state */
+        private Drawable mLanderImage;
+
+        /** Pixel width of lander image. */
+        private int mLanderWidth;
+
+        /** Used to figure out elapsed time between frames */
+        private long mLastTime;
+
+        /** Paint to draw the lines on screen. */
+        private Paint mLinePaint;
+
+        /** "Bad" speed-too-high variant of the line color. */
+        private Paint mLinePaintBad;
+
+        /** The state of the game. One of READY, RUNNING, PAUSE, LOSE, or WIN */
+        private int mMode;
+
+        /** Currently rotating, -1 left, 0 none, 1 right. */
+        private int mRotating;
+
+        /** Indicate whether the surface has been created & is ready to draw */
+        private boolean mRun = false;
+
+        /** Scratch rect object. */
+        private RectF mScratchRect;
+
+        /** Handle to the surface manager object we interact with */
+        private SurfaceHolder mSurfaceHolder;
+
+        /** Number of wins in a row. */
+        private int mWinsInARow;
+
+        /** X of lander center. */
+        private double mX;
+
+        /** Y of lander center. */
+        private double mY;
+
+        public LunarThread(SurfaceHolder surfaceHolder, Context context,
+                Handler handler) {
+            // get handles to some important objects
+            mSurfaceHolder = surfaceHolder;
+            mHandler = handler;
+            mContext = context;
+
+            Resources res = context.getResources();
+            // cache handles to our key sprites & other drawables
+            mLanderImage = context.getResources().getDrawable(
+                    R.drawable.lander_plain);
+            mFiringImage = context.getResources().getDrawable(
+                    R.drawable.lander_firing);
+            mCrashedImage = context.getResources().getDrawable(
+                    R.drawable.lander_crashed);
+
+            // load background image as a Bitmap instead of a Drawable b/c
+            // we don't need to transform it and it's faster to draw this way
+            mBackgroundImage = BitmapFactory.decodeResource(res,
+                    R.drawable.earthrise);
+
+            // Use the regular lander image as the model size for all sprites
+            mLanderWidth = mLanderImage.getIntrinsicWidth();
+            mLanderHeight = mLanderImage.getIntrinsicHeight();
+
+            // Initialize paints for speedometer
+            mLinePaint = new Paint();
+            mLinePaint.setAntiAlias(true);
+            mLinePaint.setARGB(255, 0, 255, 0);
+
+            mLinePaintBad = new Paint();
+            mLinePaintBad.setAntiAlias(true);
+            mLinePaintBad.setARGB(255, 120, 180, 0);
+
+            mScratchRect = new RectF(0, 0, 0, 0);
+
+            mWinsInARow = 0;
+            mDifficulty = DIFFICULTY_MEDIUM;
+
+            // initial show-up of lander (not yet playing)
+            mX = mLanderWidth;
+            mY = mLanderHeight * 2;
+            mFuel = PHYS_FUEL_INIT;
+            mDX = 0;
+            mDY = 0;
+            mHeading = 0;
+            mEngineFiring = true;
+        }
+
+        /**
+         * Starts the game, setting parameters for the current difficulty.
+         */
+        public void doStart() {
+            synchronized (mSurfaceHolder) {
+                // First set the game for Medium difficulty
+                mFuel = PHYS_FUEL_INIT;
+                mEngineFiring = false;
+                mGoalWidth = (int) (mLanderWidth * TARGET_WIDTH);
+                mGoalSpeed = TARGET_SPEED;
+                mGoalAngle = TARGET_ANGLE;
+                int speedInit = PHYS_SPEED_INIT;
+
+                // Adjust difficulty params for EASY/HARD
+                if (mDifficulty == DIFFICULTY_EASY) {
+                    mFuel = mFuel * 3 / 2;
+                    mGoalWidth = mGoalWidth * 4 / 3;
+                    mGoalSpeed = mGoalSpeed * 3 / 2;
+                    mGoalAngle = mGoalAngle * 4 / 3;
+                    speedInit = speedInit * 3 / 4;
+                } else if (mDifficulty == DIFFICULTY_HARD) {
+                    mFuel = mFuel * 7 / 8;
+                    mGoalWidth = mGoalWidth * 3 / 4;
+                    mGoalSpeed = mGoalSpeed * 7 / 8;
+                    speedInit = speedInit * 4 / 3;
+                }
+
+                // pick a convenient initial location for the lander sprite
+                mX = mCanvasWidth / 2;
+                mY = mCanvasHeight - mLanderHeight / 2;
+
+                // start with a little random motion
+                mDY = Math.random() * -speedInit;
+                mDX = Math.random() * 2 * speedInit - speedInit;
+                mHeading = 0;
+
+                // Figure initial spot for landing, not too near center
+                while (true) {
+                    mGoalX = (int) (Math.random() * (mCanvasWidth - mGoalWidth));
+                    if (Math.abs(mGoalX - (mX - mLanderWidth / 2)) > mCanvasHeight / 6)
+                        break;
+                }
+
+                mLastTime = System.currentTimeMillis() + 100;
+                setState(STATE_RUNNING);
+            }
+        }
+
+        /**
+         * Pauses the physics update & animation.
+         */
+        public void pause() {
+            synchronized (mSurfaceHolder) {
+                if (mMode == STATE_RUNNING) setState(STATE_PAUSE);
+            }
+        }
+
+        /**
+         * Restores game state from the indicated Bundle. Typically called when
+         * the Activity is being restored after having been previously
+         * destroyed.
+         * 
+         * @param savedState Bundle containing the game state
+         */
+        public synchronized void restoreState(Bundle savedState) {
+            synchronized (mSurfaceHolder) {
+                setState(STATE_PAUSE);
+                mRotating = 0;
+                mEngineFiring = false;
+
+                mDifficulty = savedState.getInt(KEY_DIFFICULTY);
+                mX = savedState.getDouble(KEY_X);
+                mY = savedState.getDouble(KEY_Y);
+                mDX = savedState.getDouble(KEY_DX);
+                mDY = savedState.getDouble(KEY_DY);
+                mHeading = savedState.getDouble(KEY_HEADING);
+
+                mLanderWidth = savedState.getInt(KEY_LANDER_WIDTH);
+                mLanderHeight = savedState.getInt(KEY_LANDER_HEIGHT);
+                mGoalX = savedState.getInt(KEY_GOAL_X);
+                mGoalSpeed = savedState.getInt(KEY_GOAL_SPEED);
+                mGoalAngle = savedState.getInt(KEY_GOAL_ANGLE);
+                mGoalWidth = savedState.getInt(KEY_GOAL_WIDTH);
+                mWinsInARow = savedState.getInt(KEY_WINS);
+                mFuel = savedState.getDouble(KEY_FUEL);
+            }
+        }
+
+        @Override
+        public void run() {
+            while (mRun) {
+                Canvas c = null;
+                try {
+                    c = mSurfaceHolder.lockCanvas(null);
+                    synchronized (mSurfaceHolder) {
+                        if (mMode == STATE_RUNNING) updatePhysics();
+                        doDraw(c);
+                    }
+                } finally {
+                    // do this in a finally so that if an exception is thrown
+                    // during the above, we don't leave the Surface in an
+                    // inconsistent state
+                    if (c != null) {
+                        mSurfaceHolder.unlockCanvasAndPost(c);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Dump game state to the provided Bundle. Typically called when the
+         * Activity is being suspended.
+         * 
+         * @return Bundle with this view's state
+         */
+        public Bundle saveState(Bundle map) {
+            synchronized (mSurfaceHolder) {
+                if (map != null) {
+                    map.putInt(KEY_DIFFICULTY, Integer.valueOf(mDifficulty));
+                    map.putDouble(KEY_X, Double.valueOf(mX));
+                    map.putDouble(KEY_Y, Double.valueOf(mY));
+                    map.putDouble(KEY_DX, Double.valueOf(mDX));
+                    map.putDouble(KEY_DY, Double.valueOf(mDY));
+                    map.putDouble(KEY_HEADING, Double.valueOf(mHeading));
+                    map.putInt(KEY_LANDER_WIDTH, Integer.valueOf(mLanderWidth));
+                    map.putInt(KEY_LANDER_HEIGHT, Integer
+                            .valueOf(mLanderHeight));
+                    map.putInt(KEY_GOAL_X, Integer.valueOf(mGoalX));
+                    map.putInt(KEY_GOAL_SPEED, Integer.valueOf(mGoalSpeed));
+                    map.putInt(KEY_GOAL_ANGLE, Integer.valueOf(mGoalAngle));
+                    map.putInt(KEY_GOAL_WIDTH, Integer.valueOf(mGoalWidth));
+                    map.putInt(KEY_WINS, Integer.valueOf(mWinsInARow));
+                    map.putDouble(KEY_FUEL, Double.valueOf(mFuel));
+                }
+            }
+            return map;
+        }
+
+        /**
+         * Sets the current difficulty.
+         * 
+         * @param difficulty
+         */
+        public void setDifficulty(int difficulty) {
+            synchronized (mSurfaceHolder) {
+                mDifficulty = difficulty;
+            }
+        }
+
+        /**
+         * Sets if the engine is currently firing.
+         */
+        public void setFiring(boolean firing) {
+            synchronized (mSurfaceHolder) {
+                mEngineFiring = firing;
+            }
+        }
+
+        /**
+         * Used to signal the thread whether it should be running or not.
+         * Passing true allows the thread to run; passing false will shut it
+         * down if it's already running. Calling start() after this was most
+         * recently called with false will result in an immediate shutdown.
+         * 
+         * @param b true to run, false to shut down
+         */
+        public void setRunning(boolean b) {
+            mRun = b;
+        }
+
+        /**
+         * Sets the game mode. That is, whether we are running, paused, in the
+         * failure state, in the victory state, etc.
+         * 
+         * @see #setState(int, CharSequence)
+         * @param mode one of the STATE_* constants
+         */
+        public void setState(int mode) {
+            synchronized (mSurfaceHolder) {
+                setState(mode, null);
+            }
+        }
+
+        /**
+         * Sets the game mode. That is, whether we are running, paused, in the
+         * failure state, in the victory state, etc.
+         * 
+         * @param mode one of the STATE_* constants
+         * @param message string to add to screen or null
+         */
+        public void setState(int mode, CharSequence message) {
+            /*
+             * This method optionally can cause a text message to be displayed
+             * to the user when the mode changes. Since the View that actually
+             * renders that text is part of the main View hierarchy and not
+             * owned by this thread, we can't touch the state of that View.
+             * Instead we use a Message + Handler to relay commands to the main
+             * thread, which updates the user-text View.
+             */
+            synchronized (mSurfaceHolder) {
+                mMode = mode;
+
+                if (mMode == STATE_RUNNING) {
+                    Message msg = mHandler.obtainMessage();
+                    Bundle b = new Bundle();
+                    b.putString("text", "");
+                    b.putInt("viz", View.INVISIBLE);
+                    msg.setData(b);
+                    mHandler.sendMessage(msg);
+                } else {
+                    mRotating = 0;
+                    mEngineFiring = false;
+                    Resources res = mContext.getResources();
+                    CharSequence str = "";
+                    if (mMode == STATE_READY)
+                        str = res.getText(R.string.mode_ready);
+                    else if (mMode == STATE_PAUSE)
+                        str = res.getText(R.string.mode_pause);
+                    else if (mMode == STATE_LOSE)
+                        str = res.getText(R.string.mode_lose);
+                    else if (mMode == STATE_WIN)
+                        str = res.getString(R.string.mode_win_prefix)
+                                + mWinsInARow + " "
+                                + res.getString(R.string.mode_win_suffix);
+
+                    if (message != null) {
+                        str = message + "\n" + str;
+                    }
+
+                    if (mMode == STATE_LOSE) mWinsInARow = 0;
+
+                    Message msg = mHandler.obtainMessage();
+                    Bundle b = new Bundle();
+                    b.putString("text", str.toString());
+                    b.putInt("viz", View.VISIBLE);
+                    msg.setData(b);
+                    mHandler.sendMessage(msg);
+                }
+            }
+        }
+
+        /* Callback invoked when the surface dimensions change. */
+        public void setSurfaceSize(int width, int height) {
+            // synchronized to make sure these all change atomically
+            synchronized (mSurfaceHolder) {
+                mCanvasWidth = width;
+                mCanvasHeight = height;
+
+                // don't forget to resize the background image
+                mBackgroundImage = mBackgroundImage.createScaledBitmap(
+                        mBackgroundImage, width, height, true);
+            }
+        }
+
+        /**
+         * Resumes from a pause.
+         */
+        public void unpause() {
+            // Move the real time clock up to now
+            synchronized (mSurfaceHolder) {
+                mLastTime = System.currentTimeMillis() + 100;
+            }
+            setState(STATE_RUNNING);
+        }
+
+        /**
+         * Handles a key-down event.
+         * 
+         * @param keyCode the key that was pressed
+         * @param msg the original event object
+         * @return true
+         */
+        boolean doKeyDown(int keyCode, KeyEvent msg) {
+            synchronized (mSurfaceHolder) {
+                boolean okStart = false;
+                if (keyCode == KeyEvent.KEYCODE_DPAD_UP) okStart = true;
+                if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) okStart = true;
+                if (keyCode == KeyEvent.KEYCODE_S) okStart = true;
+
+                boolean center = (keyCode == KeyEvent.KEYCODE_DPAD_UP);
+
+                if (okStart
+                        && (mMode == STATE_READY || mMode == STATE_LOSE || mMode == STATE_WIN)) {
+                    // ready-to-start -> start
+                    doStart();
+                    return true;
+                } else if (mMode == STATE_PAUSE && okStart) {
+                    // paused -> running
+                    unpause();
+                    return true;
+                } else if (mMode == STATE_RUNNING) {
+                    // center/space -> fire
+                    if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
+                            || keyCode == KeyEvent.KEYCODE_SPACE) {
+                        setFiring(true);
+                        return true;
+                        // left/q -> left
+                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
+                            || keyCode == KeyEvent.KEYCODE_Q) {
+                        mRotating = -1;
+                        return true;
+                        // right/w -> right
+                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
+                            || keyCode == KeyEvent.KEYCODE_W) {
+                        mRotating = 1;
+                        return true;
+                        // up -> pause
+                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+                        pause();
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        }
+
+        /**
+         * Handles a key-up event.
+         * 
+         * @param keyCode the key that was pressed
+         * @param msg the original event object
+         * @return true if the key was handled and consumed, or else false
+         */
+        boolean doKeyUp(int keyCode, KeyEvent msg) {
+            boolean handled = false;
+
+            synchronized (mSurfaceHolder) {
+                if (mMode == STATE_RUNNING) {
+                    if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
+                            || keyCode == KeyEvent.KEYCODE_SPACE) {
+                        setFiring(false);
+                        handled = true;
+                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
+                            || keyCode == KeyEvent.KEYCODE_Q
+                            || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
+                            || keyCode == KeyEvent.KEYCODE_W) {
+                        mRotating = 0;
+                        handled = true;
+                    }
+                }
+            }
+
+            return handled;
+        }
+
+        /**
+         * Draws the ship, fuel/speed bars, and background to the provided
+         * Canvas.
+         */
+        private void doDraw(Canvas canvas) {
+            // Draw the background image. Operations on the Canvas accumulate
+            // so this is like clearing the screen.
+            canvas.drawBitmap(mBackgroundImage, 0, 0, null);
+
+            int yTop = mCanvasHeight - ((int) mY + mLanderHeight / 2);
+            int xLeft = (int) mX - mLanderWidth / 2;
+
+            // Draw the fuel gauge
+            int fuelWidth = (int) (UI_BAR * mFuel / PHYS_FUEL_MAX);
+            mScratchRect.set(4, 4, 4 + fuelWidth, 4 + UI_BAR_HEIGHT);
+            canvas.drawRect(mScratchRect, mLinePaint);
+
+            // Draw the speed gauge, with a two-tone effect
+            double speed = Math.sqrt(mDX * mDX + mDY * mDY);
+            int speedWidth = (int) (UI_BAR * speed / PHYS_SPEED_MAX);
+
+            if (speed <= mGoalSpeed) {
+                mScratchRect.set(4 + UI_BAR + 4, 4,
+                        4 + UI_BAR + 4 + speedWidth, 4 + UI_BAR_HEIGHT);
+                canvas.drawRect(mScratchRect, mLinePaint);
+            } else {
+                // Draw the bad color in back, with the good color in front of
+                // it
+                mScratchRect.set(4 + UI_BAR + 4, 4,
+                        4 + UI_BAR + 4 + speedWidth, 4 + UI_BAR_HEIGHT);
+                canvas.drawRect(mScratchRect, mLinePaintBad);
+                int goalWidth = (UI_BAR * mGoalSpeed / PHYS_SPEED_MAX);
+                mScratchRect.set(4 + UI_BAR + 4, 4, 4 + UI_BAR + 4 + goalWidth,
+                        4 + UI_BAR_HEIGHT);
+                canvas.drawRect(mScratchRect, mLinePaint);
+            }
+
+            // Draw the landing pad
+            canvas.drawLine(mGoalX, 1 + mCanvasHeight - TARGET_PAD_HEIGHT,
+                    mGoalX + mGoalWidth, 1 + mCanvasHeight - TARGET_PAD_HEIGHT,
+                    mLinePaint);
+
+
+            // Draw the ship with its current rotation
+            canvas.save();
+            canvas.rotate((float) mHeading, (float) mX, mCanvasHeight
+                    - (float) mY);
+            if (mMode == STATE_LOSE) {
+                mCrashedImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop
+                        + mLanderHeight);
+                mCrashedImage.draw(canvas);
+            } else if (mEngineFiring) {
+                mFiringImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop
+                        + mLanderHeight);
+                mFiringImage.draw(canvas);
+            } else {
+                mLanderImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop
+                        + mLanderHeight);
+                mLanderImage.draw(canvas);
+            }
+            canvas.restore();
+        }
+
+        /**
+         * Figures the lander state (x, y, fuel, ...) based on the passage of
+         * realtime. Does not invalidate(). Called at the start of draw().
+         * Detects the end-of-game and sets the UI to the next state.
+         */
+        private void updatePhysics() {
+            long now = System.currentTimeMillis();
+
+            // Do nothing if mLastTime is in the future.
+            // This allows the game-start to delay the start of the physics
+            // by 100ms or whatever.
+            if (mLastTime > now) return;
+
+            double elapsed = (now - mLastTime) / 1000.0;
+
+            // mRotating -- update heading
+            if (mRotating != 0) {
+                mHeading += mRotating * (PHYS_SLEW_SEC * elapsed);
+
+                // Bring things back into the range 0..360
+                if (mHeading < 0)
+                    mHeading += 360;
+                else if (mHeading >= 360) mHeading -= 360;
+            }
+
+            // Base accelerations -- 0 for x, gravity for y
+            double ddx = 0.0;
+            double ddy = -PHYS_DOWN_ACCEL_SEC * elapsed;
+
+            if (mEngineFiring) {
+                // taking 0 as up, 90 as to the right
+                // cos(deg) is ddy component, sin(deg) is ddx component
+                double elapsedFiring = elapsed;
+                double fuelUsed = elapsedFiring * PHYS_FUEL_SEC;
+
+                // tricky case where we run out of fuel partway through the
+                // elapsed
+                if (fuelUsed > mFuel) {
+                    elapsedFiring = mFuel / fuelUsed * elapsed;
+                    fuelUsed = mFuel;
+
+                    // Oddball case where we adjust the "control" from here
+                    mEngineFiring = false;
+                }
+
+                mFuel -= fuelUsed;
+
+                // have this much acceleration from the engine
+                double accel = PHYS_FIRE_ACCEL_SEC * elapsedFiring;
+
+                double radians = 2 * Math.PI * mHeading / 360;
+                ddx = Math.sin(radians) * accel;
+                ddy += Math.cos(radians) * accel;
+            }
+
+            double dxOld = mDX;
+            double dyOld = mDY;
+
+            // figure speeds for the end of the period
+            mDX += ddx;
+            mDY += ddy;
+
+            // figure position based on average speed during the period
+            mX += elapsed * (mDX + dxOld) / 2;
+            mY += elapsed * (mDY + dyOld) / 2;
+
+            mLastTime = now;
+
+            // Evaluate if we have landed ... stop the game
+            double yLowerBound = TARGET_PAD_HEIGHT + mLanderHeight / 2
+                    - TARGET_BOTTOM_PADDING;
+            if (mY <= yLowerBound) {
+                mY = yLowerBound;
+
+                int result = STATE_LOSE;
+                CharSequence message = "";
+                Resources res = mContext.getResources();
+                double speed = Math.sqrt(mDX * mDX + mDY * mDY);
+                boolean onGoal = (mGoalX <= mX - mLanderWidth / 2 && mX
+                        + mLanderWidth / 2 <= mGoalX + mGoalWidth);
+
+                // "Hyperspace" win -- upside down, going fast,
+                // puts you back at the top.
+                if (onGoal && Math.abs(mHeading - 180) < mGoalAngle
+                        && speed > PHYS_SPEED_HYPERSPACE) {
+                    result = STATE_WIN;
+                    mWinsInARow++;
+                    doStart();
+
+                    return;
+                    // Oddball case: this case does a return, all other cases
+                    // fall through to setMode() below.
+                } else if (!onGoal) {
+                    message = res.getText(R.string.message_off_pad);
+                } else if (!(mHeading <= mGoalAngle || mHeading >= 360 - mGoalAngle)) {
+                    message = res.getText(R.string.message_bad_angle);
+                } else if (speed > mGoalSpeed) {
+                    message = res.getText(R.string.message_too_fast);
+                } else {
+                    result = STATE_WIN;
+                    mWinsInARow++;
+                }
+
+                setState(result, message);
+            }
+        }
+    }
+
+    /** Handle to the application context, used to e.g. fetch Drawables. */
+    private Context mContext;
+
+    /** Pointer to the text view to display "Paused.." etc. */
+    private TextView mStatusText;
+
+    /** The thread that actually draws the animation */
+    private LunarThread thread;
+
+    public LunarView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        // register our interest in hearing about changes to our surface
+        SurfaceHolder holder = getHolder();
+        holder.addCallback(this);
+
+        // create thread only; it's started in surfaceCreated()
+        thread = new LunarThread(holder, context, new Handler() {
+            @Override
+            public void handleMessage(Message m) {
+                mStatusText.setVisibility(m.getData().getInt("viz"));
+                mStatusText.setText(m.getData().getString("text"));
+            }
+        });
+
+        setFocusable(true); // make sure we get key events
+    }
+
+    /**
+     * Fetches the animation thread corresponding to this LunarView.
+     * 
+     * @return the animation thread
+     */
+    public LunarThread getThread() {
+        return thread;
+    }
+
+    /**
+     * Standard override to get key-press events.
+     */
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent msg) {
+        return thread.doKeyDown(keyCode, msg);
+    }
+
+    /**
+     * Standard override for key-up. We actually care about these, so we can
+     * turn off the engine or stop rotating.
+     */
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent msg) {
+        return thread.doKeyUp(keyCode, msg);
+    }
+
+    /**
+     * Standard window-focus override. Notice focus lost so we can pause on
+     * focus lost. e.g. user switches to take a call.
+     */
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        if (!hasWindowFocus) thread.pause();
+    }
+
+    /**
+     * Installs a pointer to the text view used for messages.
+     */
+    public void setTextView(TextView textView) {
+        mStatusText = textView;
+    }
+
+    /* Callback invoked when the surface dimensions change. */
+    public void surfaceChanged(SurfaceHolder holder, int format, int width,
+            int height) {
+        thread.setSurfaceSize(width, height);
+    }
+
+    /*
+     * Callback invoked when the Surface has been created and is ready to be
+     * used.
+     */
+    public void surfaceCreated(SurfaceHolder holder) {
+        // start the thread here so that we don't busy-wait in run()
+        // waiting for the surface to be created
+        thread.setRunning(true);
+        thread.start();
+    }
+
+    /*
+     * Callback invoked when the Surface has been destroyed and must no longer
+     * be touched. WARNING: after this method returns, the Surface/Canvas must
+     * never be touched again!
+     */
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // we have to tell thread to shut down & wait for it to finish, or else
+        // it might touch the Surface after we return and explode
+        boolean retry = true;
+        thread.setRunning(false);
+        while (retry) {
+            try {
+                thread.join();
+                retry = false;
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+}
diff --git a/samples/LunarLander/tests/Android.mk b/samples/LunarLander/tests/Android.mk
new file mode 100644
index 0000000..60208cf
--- /dev/null
+++ b/samples/LunarLander/tests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := LunarLanderTests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_INSTRUMENTATION_FOR := LunarLander
+
+include $(BUILD_PACKAGE)
diff --git a/samples/LunarLander/tests/AndroidManifest.xml b/samples/LunarLander/tests/AndroidManifest.xml
new file mode 100644
index 0000000..1bc8364
--- /dev/null
+++ b/samples/LunarLander/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.lunarlander.tests">
+    
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+  <instrumentation android:name="android.test.InstrumentationTestRunner"
+      android:targetPackage="com.example.android.lunarlander"
+      android:label="LunarLander sample tests">
+  </instrumentation>  
+  
+</manifest>
diff --git a/samples/LunarLander/tests/src/com/example/android/lunarlander/LunarLanderTest.java b/samples/LunarLander/tests/src/com/example/android/lunarlander/LunarLanderTest.java
new file mode 100644
index 0000000..fae02da
--- /dev/null
+++ b/samples/LunarLander/tests/src/com/example/android/lunarlander/LunarLanderTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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.lunarlander;
+
+import android.test.ActivityInstrumentationTestCase;
+
+import com.example.android.lunarlander.LunarLander;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class LunarLanderTest extends ActivityInstrumentationTestCase<LunarLander> {
+
+  public LunarLanderTest() {
+      super("com.example.android.lunarlander", LunarLander.class);
+  }
+  
+}
diff --git a/samples/MailSync/res/values/ids.xml b/samples/MailSync/res/values/ids.xml
new file mode 100644
index 0000000..ee736a6
--- /dev/null
+++ b/samples/MailSync/res/values/ids.xml
@@ -0,0 +1,21 @@
+<?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>
+    <item type="id" name="from" />
+    <item type="id" name="snippet" />
+    <item type="id" name="subject" />
+</resources>
diff --git a/samples/MySampleRss/Android.mk b/samples/MySampleRss/Android.mk
new file mode 100644
index 0000000..fea9729
--- /dev/null
+++ b/samples/MySampleRss/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_PACKAGE_NAME := MyRSSReader
+
+LOCAL_SDK_VERSION := current
+
+##include $(BUILD_PACKAGE)
diff --git a/samples/MySampleRss/AndroidManifest.xml b/samples/MySampleRss/AndroidManifest.xml
new file mode 100755
index 0000000..575c81e
--- /dev/null
+++ b/samples/MySampleRss/AndroidManifest.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.codelab.rssexample">
+    <application android:name="MyRssReader" android:label="My Rss Reader">
+        <activity>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name="MyRssReader2" android:label="My Rss Reader V2">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+       </activity>
+       <activity android:name="MyRssReader3" android:label="@string/reader_3_label">
+           <intent-filter>
+               <action android:name="android.intent.action.MAIN" /> 
+               <category android:name="android.intent.category.DEFAULT" />
+               <category android:name="android.intent.category.LAUNCHER" />
+           </intent-filter>
+       </activity>
+       <activity android:name="MyRssReader4" android:label="@string/reader_4_label">
+           <intent-filter>
+               <action android:name="android.intent.action.MAIN" />
+               <category android:name="android.intent.category.DEFAULT" />
+               <category android:name="android.intent.category.LAUNCHER" />
+           </intent-filter>
+       </activity>
+       <activity android:name="MyRssReader5" android:label="@string/reader_5_label">
+           <intent-filter>
+               <action android:name="android.intent.action.MAIN" />
+               <category android:name="android.intent.category.DEFAULT" />
+               <category android:name="android.intent.category.LAUNCHER" />
+           </intent-filter>
+       </activity> 
+       <activity android:name="AddRssItem" android:label="@string/add_item_label" android:theme="@android:style/Theme.Dialog"/>
+       <provider android:name="RssContentProvider" android:authorities="my_rss_item" android:multiprocess="true" />
+       <service android:name="RssService" android:process=":myrss"/>
+    </application>
+</manifest> 
+
+
diff --git a/samples/MySampleRss/res/drawable/rss_icon.PNG b/samples/MySampleRss/res/drawable/rss_icon.PNG
new file mode 100755
index 0000000..214a38d
--- /dev/null
+++ b/samples/MySampleRss/res/drawable/rss_icon.PNG
Binary files differ
diff --git a/samples/MySampleRss/res/layout/add_item.xml b/samples/MySampleRss/res/layout/add_item.xml
new file mode 100644
index 0000000..8191bf5
--- /dev/null
+++ b/samples/MySampleRss/res/layout/add_item.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_height="fill_parent"
+                android:layout_width="fill_parent">
+                
+                <TextView android:id="@+id/title_label"
+                          android:layout_height="wrap_content"
+                          android:layout_width="wrap_content"
+                          android:layout_alignParentTop="true"
+                          android:layout_alignParentLeft="true"
+                          android:text="@string/add_item_title"/>
+                <EditText android:id="@+id/title_textbox"
+                          android:layout_height="wrap_content"
+                          android:layout_width="fill_parent"
+                          android:layout_toRightOf="@id/title_label"/>
+                <EditText android:id="@+id/url_textbox"
+                          android:layout_height="wrap_content"
+                          android:layout_width="fill_parent"
+                          android:layout_below="@id/title_textbox"
+                          android:layout_alignLeft="@id/title_textbox"/>
+                          
+                <!-- Note that we declare url_label *after* url_textbox in this file
+                because it references url_textbox, and a resource file is
+                evaluated sequentially. -->                           
+                <TextView android:id="@+id/url_label"
+                          android:layout_height="wrap_content"
+                          android:layout_width="wrap_content"
+                          android:layout_toRightOf="url_textbox"
+                          android:layout_alignTop="@id/url_textbox"
+                          android:text="@string/add_item_url"/>
+                <Button android:id="@+id/submit"
+                        android:layout_height="wrap_content"
+                        android:layout_width="wrap_content"
+                        android:layout_alignParentRight="true"
+                        android:layout_alignParentBottom="true"
+                        android:text="@string/submit"/>            
+                <Button android:id="@+id/cancel"
+                        android:layout_height="wrap_content"
+                        android:layout_width="wrap_content"
+                        android:layout_toLeftOf="@id/submit"
+                        android:layout_alignTop="@id/submit"
+                        android:text="@string/cancel"/>                         
+</RelativeLayout>
+                
diff --git a/samples/MySampleRss/res/layout/list_element.xml b/samples/MySampleRss/res/layout/list_element.xml
new file mode 100644
index 0000000..4255d86
--- /dev/null
+++ b/samples/MySampleRss/res/layout/list_element.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+  <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:id="@+id/list_item"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"/>
diff --git a/samples/MySampleRss/res/layout/main_screen.xml b/samples/MySampleRss/res/layout/main_screen.xml
new file mode 100755
index 0000000..5292bb2
--- /dev/null
+++ b/samples/MySampleRss/res/layout/main_screen.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_height="fill_parent"
+              android:layout_width="fill_parent"
+              android:orientation="vertical"
+              android:scrollbars="vertical">
+                  
+        <ListView android:id="@+id/rssListView"
+                  android:layout_height="0px"
+                  android:layout_width="fill_parent"
+                  android:layout_weight="1"
+                  android:background="#00CC00"/>
+                  
+				<WebView android:id="@+id/rssWebView"
+			             android:background="#77CC0000"
+				         android:layout_height="0px"
+				         android:layout_width="fill_parent"
+				         android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/samples/MySampleRss/res/layout/main_screen2.xml b/samples/MySampleRss/res/layout/main_screen2.xml
new file mode 100644
index 0000000..36b0af4
--- /dev/null
+++ b/samples/MySampleRss/res/layout/main_screen2.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_height="fill_parent" 
+              android:layout_width="fill_parent"
+              android:orientation="vertical"
+              android:scrollbars="vertical">
+	                 
+	       <ListView android:id="@+id/rssListView" 
+	                 android:layout_height="0px"
+	                 android:layout_width="fill_parent"
+	                 android:layout_weight="1"
+	                 android:background="#9900FF00"/>
+                  
+				<WebView android:id="@+id/rssWebView"
+				         android:layout_height="0px"
+				         android:layout_width="fill_parent"
+				         android:layout_weight="2"/>
+</LinearLayout>
diff --git a/samples/MySampleRss/res/values/strings.xml b/samples/MySampleRss/res/values/strings.xml
new file mode 100644
index 0000000..8655995
--- /dev/null
+++ b/samples/MySampleRss/res/values/strings.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+    <string name="menu_option_start">Start RSS Service</string>
+    <string name="menu_option_stop">Stop RSS Service</string>
+    <string name="menu_option_add">Add New Feed</string>
+    <string name="menu_option_delete">Delete Feed</string>
+    <string name="menu_option_update">Update All Feeds</string>
+    <string name="add_item_title">Title</string>
+    <string name="add_item_url">URL</string>
+    <string name="submit">Submit</string>
+    <string name="cancel">Cancel</string>
+    <string name="reader_3_label">MyRssReader3</string>
+    <string name="reader_4_label">MyRssReader4</string>
+    <string name="reader_5_label">MyRssReader5</string>
+    <string name="add_item_label">Add a new Feed</string>
+</resources>
\ No newline at end of file
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/AddRssItem.java b/samples/MySampleRss/src/com/example/codelab/rssexample/AddRssItem.java
new file mode 100644
index 0000000..980eec6
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/AddRssItem.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.view.View.OnClickListener;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.text.TextUtils;
+import android.os.Bundle;
+
+/*** Form to add a new RSS feed.
+ It is a dialog form,**/ 
+public class AddRssItem extends Activity {
+    
+    // Button handler for Submit/Cancel.
+    // It is a dialog style form because it's declared as such
+    // in the manifest.
+    private OnClickListener mClickListener = new OnClickListener(){
+        public void onClick(View v){
+            if(v.getId() == R.id.submit){
+                String title = ((TextView) findViewById(R.id.title_textbox)).getText().toString();
+                String url = ((TextView) findViewById(R.id.url_textbox)).getText().toString();
+                if(TextUtils.isEmpty(title) || TextUtils.isEmpty(url)){
+                    showAlert("Missing Values", 
+                              "You must specify both a title and a URL value", 
+                              "OK", 
+                              null, false, null);
+                    return;
+                }
+                Intent res = new Intent("Accepted");
+                res.putExtra(RssContentProvider.TITLE, title);
+                res.putExtra(RssContentProvider.URL, url);
+                res.putExtra(RssContentProvider.LAST_UPDATED, 0);
+                res.putExtra(RssContentProvider.CONTENT, "<html><body><h2>Not updated yet.</h2></body></html>");
+                setResult(RESULT_OK, res);
+            }
+            else
+                setResult(RESULT_CANCELED, (new Intent()).setAction("Canceled" + v.getId()));
+            
+            finish();
+            
+        }
+    };
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.add_item);
+        setTitle(getString(R.string.add_item_label));
+        
+        Button btn = (Button) findViewById(R.id.cancel);
+        btn.setOnClickListener(mClickListener);
+        
+        btn = (Button) findViewById(R.id.submit);
+        btn.setOnClickListener(mClickListener);       
+    }
+
+}
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader.java b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader.java
new file mode 100644
index 0000000..d306554
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+//BEGIN_INCLUDE(1_1)  
+public class MyRssReader extends Activity {
+    /** Called with the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        
+        // Load screen layout.
+        setContentView(R.layout.main_screen);
+
+//END_INCLUDE(1_1)
+//BEGIN_INCLUDE(1_2)        
+        // Load some simple values into the ListView
+        mRssList = (ListView) findViewById(R.id.rssListView);
+        mRssList.setAdapter(
+                new ArrayAdapter<String>(
+                        this, 
+                        R.layout.list_element, 
+                        new String[] { "Scientific American", "BBC", "The Onion", "Engadget" }));
+//END_INCLUDE(1_2)
+}
+    
+    // Store our state before we are potentially bumped from memory.
+    // We'd like to store the current ListView selection.
+    @Override
+    protected void onSaveInstanceState(Bundle outState){
+        int index = mRssList.getSelectedItemIndex();
+        if(index > -1){
+            outState.putInteger("lastIndexItem", index);
+        }
+    }
+
+    // Add our initial menu options. We will tweak this menu when it's loaded swap out 
+    // "start service" or "stop service", depending on whether the service is currently running.
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu){
+        // Always call the superclass implementation to 
+        // provide standard items.
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, 0, "Start RSS Service", null);
+        menu.add(0, 1, "Stop RSS Service", null);
+        menu.add(0, 2, "Add New Feed", null);
+        menu.add(0, 3, "Delete Feed", null);
+        menu.add(0, 4, "Update All Feeds", null);
+        
+        return true;
+    }  
+     
+    // Toggle out start service/stop service depending on whether the service is running.
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu){
+        return true;
+    }
+    
+    // Handle our menu clicks.
+    @Override
+    public boolean onOptionsItemSelected(Menu.Item item){
+        switch (item.getId()) {
+            case 0:
+                showAlert(null, "You clicked 'start'!", "ok", null, false, null);
+                break;
+            case 1:
+                showAlert(null, "You clicked stop!", "ok", null, false, null);
+                break;
+            case 2:
+                showAlert(null, "You clicked 'Add'!", "ok", null, false, null);
+                break;
+            case 3:
+                showAlert(null, "You clicked 'Delete'!", "ok", null, false, null);
+                break;
+            case 4:
+                showAlert(null, "You clicked 'Update'!", "ok", null, false, null);
+                break;
+            default:
+                showAlert(null, "I have no idea what you clicked!", "ok", null, false, null);
+                break;
+        }
+        return true;
+    }
+
+    ListView mRssList;
+}
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader2.java b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader2.java
new file mode 100644
index 0000000..352167a
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader2.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.view.Menu;
+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;
+import java.util.logging.Logger;
+public class MyRssReader2 extends Activity{
+    private ArrayList<RssItem> mFeeds = null;
+    ListView mRssList = null;
+    private Logger mLogger = Logger.getLogger("com.example.codelab.rssexample");
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+
+        // Load screen layout.
+        setContentView(R.layout.main_screen2);
+        
+       // Populate our list
+        mFeeds = initializeList();
+        mLogger.info("MyRssReader.onCreate-1  mFeeds value:" + mFeeds.size());
+// BEGIN_INCLUDE(2_2)       
+        // Populate ArrayAdapter and bind it to ListView
+        mRssList = (ListView)findViewById(R.id.rssListView);
+        if(mRssList == null){
+            // Note: Calling showAlert() would fail here because dialogs opened
+            // in onCreate won't be displayed properly, if at all.
+            mLogger.warning("MyRssReader.onCreate-2 -- Couldn't instantiate a ListView!");
+        }
+        RssDataAdapter<RssItem> adap = new RssDataAdapter<RssItem>(this, R.layout.add_item, mFeeds);
+        if(adap == null){
+            mLogger.warning("MyRssReader.onCreate-3 -- Couldn't instantiate RssDataAdapter!");
+        }
+        if(mFeeds == null){
+            mLogger.warning("MyRssReader.onCreate-4 -- Couldn't instantiate a ListView!");
+        }
+        mRssList.setAdapter(adap);   
+// END_INCLUDE(2_2)
+       
+        mLogger.info("MyRssReader.onCreate-5 -- Loading preferences.");
+        // Set the last selected item.
+        // (icicle is only set if this is being restarted).
+        if(savedInstanceState != null && savedInstanceState.containsKey("lastIndexItem"))
+        {
+            Integer selectedItem = savedInstanceState.getInteger("lastIndexItem");
+            if(selectedItem >= 0 && selectedItem < mRssList.getChildCount()){
+                mRssList.setSelection(savedInstanceState.getInteger("lastIndexItem"));
+            }
+            mLogger.info("MyRssReader.onCreate-6 -- Last selected item:" + selectedItem);
+        }
+    }
+    
+    // Store our state before we are potentially bumped from memory.
+    // We'd like to store the current ListView selection.
+    @Override
+    protected void onSaveInstanceState(Bundle outState){
+        int index = mRssList.getSelectedItemIndex();
+        if(index > -1){
+            outState.putInteger("lastIndexItem", index);
+        }
+    }
+    
+    
+   
+    // Add our initial menu options. We will tweak this menu when it's loaded swap out 
+    // "start service" or "stop service", depending on whether the service is currently running.
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu){
+        // Always call the superclass implementation to 
+        // provide standard items.
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, 0, "Start RSS Service", null);
+        menu.add(0, 1, "Stop RSS Service", null);
+        menu.add(0, 2, "Add New Feed", null);
+        menu.add(0, 3, "Delete Feed", null);
+        menu.add(0, 4, "Update All Feeds", null);
+        
+        return true;
+    }
+    
+    // Toggle out start service/stop service depending on whether the service is running.
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu){
+        return true;
+    }
+    
+    // Handle our menu clicks.
+    @Override
+    public boolean onOptionsItemSelected(Menu.Item item){
+        switch (item.getId()){
+            case 0:
+              showAlert(null, "You clicked 'start'!", "ok", null, false, null);
+              break;
+            case 1:
+              showAlert(null, "You clicked stop!", "ok", null, false, null);
+              break;
+            case 2:
+                showAlert(null, "You clicked 'Add'!", "ok", null, false, null);
+                break;
+            case 3:
+                showAlert(null, "You clicked 'Delete'!", "ok", null, false, null);
+                break;
+            case 4:
+                showAlert(null, "You clicked 'Update'!", "ok", null, false, null);
+                break;
+            default:
+                showAlert(null, "I have no idea what you clicked!", "ok", null, false, null);
+                break;
+            }
+        return true;
+    }
+    
+    
+    // Our private ArrayAdapter implementation that returns a bold TextView for 
+    // RSS items that are unread, or a normal TextView for items that have been read.
+// BEGIN_INCLUDE(2_3)    
+    private class RssDataAdapter<T> extends ArrayAdapter<T> {
+        public RssDataAdapter(Context context, int resource, List objects) {
+            super(context, resource, objects);
+        }
+// END_INCLUDE(2_3)       
+        // Here's our only important override--returning the list item.
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent){
+            TextView view = null;
+            // Get the item from the underlying array,
+            // Create a TextView wrapper, and change the typeface, if necessary.
+            RssItem item = (RssItem)this.getItem(position);
+            if(item != null)
+            {
+                view = new TextView(parent.getContext());
+                view.setText(item.toString());
+                
+                if(! item.hasBeenRead){
+                    Typeface type = view.getTypeface();
+                    view.setTypeface(Typeface.create(type, Typeface.BOLD_ITALIC));
+                }
+            }
+            return view;    
+        }
+     }
+
+//BEGIN_INCLUDE(2_1) 
+    // Method to initialize our list of RSS items.
+    private ArrayList<RssItem> initializeList(){
+        ArrayList<RssItem> list = new ArrayList<RssItem>();
+        list.add(new RssItem("http://www.sciam.com/xml/sciam.xml", "Scientific American"));
+        list.add(new RssItem("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml", "BBC"));
+        list.add(new RssItem("http://www.theonion.com/content/feeds/daily.", "The Onion"));
+        list.add(new RssItem("http://feeds.engadget.com/weblogsinc/engadget", "Engadget"));
+        return list;
+    }
+//END_INCLUDE(2_1)     
+}
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader3.java b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader3.java
new file mode 100644
index 0000000..1ffe33e
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader3.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.view.Menu;
+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;
+
+public class MyRssReader3 extends Activity{
+
+    private ArrayList<RssItem> mFeeds;
+    ListView mRssList;
+    ArrayAdapter mAdap;
+    private static final int ADD_ELEMENT_REQUEST = 1;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        
+        // Load screen layout.
+        setContentView(R.layout.main_screen2);
+        
+       // Populate our list
+        mFeeds = initializeList();
+        
+         // Populate ArrayAdapter and bind it to ListView
+        mRssList = (ListView)findViewById(R.id.rssListView);
+        mAdap = new RssDataAdapter<RssItem>(this, R.layout.list_element, mFeeds);
+        mRssList.setAdapter(mAdap);   
+        
+        // Set the last selected item.
+        // (icicle is only set if this is being restarted).
+        if(savedInstanceState != null && savedInstanceState.containsKey("lastIndexItem"))
+            mRssList.setSelection(savedInstanceState.getInteger("lastIndexItem"));
+    }
+    
+    // Store our state before we are potentially bumped from memory.
+    // We'd like to store the current ListView selection.
+    @Override
+    protected void onSaveInstanceState(Bundle outState){
+        int index = mRssList.getSelectedItemIndex();
+        if(index > -1){
+            outState.putInteger("lastIndexItem", index);     
+        }
+    }
+    
+   
+    // Add our initial menu options. We will tweak this menu when it's loaded swap out 
+    // "start service" or "stop service", depending on whether the service is currently running.
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+        // Always call the superclass implementation to 
+        // provide standard items.
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, 0, R.string.menu_option_start, null);
+        menu.add(0, 1, R.string.menu_option_stop, null);
+        menu.add(0, 2, R.string.menu_option_add, null);
+        menu.add(0, 3, R.string.menu_option_delete, null);
+        menu.add(0, 4, R.string.menu_option_update, null);
+        
+        return true;
+    }
+    
+    // Toggle out start service/stop service depending on whether the service is running.
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu){
+        return true;
+    }
+    
+    // Handle our menu clicks.
+    @Override
+    public boolean onOptionsItemSelected(Menu.Item item){
+        super.onOptionsItemSelected(item);
+        
+        switch (item.getId()){
+            case 0:     // Start service
+                showAlert(null, "You clicked 'start'!", "ok", null, false, null);
+                break;
+            case 1:    // Stop service
+                showAlert(null, "You clicked stop!", "ok", null, false, null);
+                break;
+            case 2:     // Add Item
+                Intent addIntent = new Intent(AddRssItem.class);
+
+                // Use an ID so that if we create a "remove item" form we
+                // can tell which form is returning a value.
+                startActivityForResult(addIntent, ADD_ELEMENT_REQUEST);
+                break;
+            case 3:     // Delete item.
+                if(mRssList.hasFocus()){
+                    Object selectedItem = mRssList.getSelectedItem();
+                    mAdap.removeObject(mRssList.getSelectedItem());
+                }
+                break;
+            case 4:    // Update all
+                showAlert(null, "You clicked 'Update'!", "ok", null, false, null);
+                break;
+            default:
+                showAlert(null, "I have no idea what you clicked!", "ok", null, false, null);
+                break;
+        }
+        return true;
+    }
+    
+    // Called by the "Add RSS Item" floating screen when it closes.
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data){
+        if(resultCode == RESULT_OK){
+            switch (requestCode){
+                case ADD_ELEMENT_REQUEST:
+                    RssItem newIt = new RssItem(
+                            data.getStringExtra("url").toString(), 
+                            data.getStringExtra("title").toString());
+                    mAdap.addObject(newIt);
+                    mRssList.setSelection(mRssList.getCount() - 1);
+                break;
+                default:
+                    break;
+            }
+        }
+    }
+    
+    // Our private ArrayAdapter implementation that returns a bold TextView for 
+    // RSS items that are unread, or a normal TextView for items that have been read.
+    private class RssDataAdapter<T> extends ArrayAdapter<T> {
+        public RssDataAdapter(Context context, int resource, List objects) {
+            super(context, resource, objects);
+        }
+        
+        // Here's our only important override--returning the list item.
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent){
+            
+            // Get the item from the underlying array,
+            // Create a TextView wrapper, and change the typeface, if necessary.
+            RssItem item = (RssItem)this.getItem(position);
+            TextView view = new TextView(parent.getContext());
+            view.setText(item.toString());
+            
+            if(! item.hasBeenRead){
+                Typeface type = view.getTypeface();
+                view.setTypeface(Typeface.create(type, Typeface.BOLD_ITALIC));
+            }
+            return view;
+        }
+    }
+
+    // Method to initialize our list of RSS items.
+    private ArrayList<RssItem> initializeList(){
+      ArrayList<RssItem> list = new ArrayList<RssItem>();
+      list.add(new RssItem("http://www.sciam.com/xml/sciam.xml", "Scientific American"));
+      list.add(new RssItem("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml", "BBC"));
+      list.add(new RssItem("http://feeds.theonion.com/theonion/daily", "The Onion"));
+      list.add(new RssItem("http://feeds.engadget.com/weblogsinc/engadget", "Engadget"));
+      return list;
+    }
+}
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader4.java b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader4.java
new file mode 100644
index 0000000..bc37786
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader4.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.SimpleCursorAdapter;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+
+
+public class MyRssReader4 extends Activity {
+
+    ListView mRssList;
+    Cursor mCur;
+    RssCursorAdapter mAdap;
+    private static final int ADD_ELEMENT_REQUEST = 1;
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        
+        // Load screen layout.
+        setContentView(R.layout.main_screen2);
+       
+         // Populate ArrayAdapter and bind it to ListView
+        mRssList = (ListView)findViewById(R.id.rssListView);
+        
+        mCur = managedQuery(RssContentProvider.CONTENT_URI, // Query for all items.
+                            null, 
+                            null, 
+                            RssContentProvider.DEFAULT_SORT_ORDER);
+// BEGIN_INCLUDE(4_1)                           
+        mAdap = new RssCursorAdapter(
+                this,
+                R.layout.list_element,                  // Our layout resource.
+                mCur, 
+                new String[]{RssContentProvider.TITLE}, // Columns to retrieve.
+                new int[]{R.id.list_item});             // IDs of widgets to display
+        mRssList.setAdapter(mAdap);                     //    the corresponding column.
+// END_INCLUDE(4_1)
+        
+        // Set the last selected item.
+        // (icicle is only set if this is being restarted).
+        if(savedInstanceState != null && savedInstanceState.containsKey("lastIndexItem")){
+            mRssList.setSelection(savedInstanceState.getInteger("lastIndexItem"));
+        }
+    }
+   
+    // Store our state before we are potentially bumped from memory.
+    // We'd like to store the current ListView selection.
+    @Override
+    protected void onSaveInstanceState(Bundle outState){
+        int index = mRssList.getSelectedItemIndex();
+        if(index > -1){
+            outState.putInteger("lastIndexItem", index);
+        }
+    }
+    
+    
+    // Add our initial menu options. We will tweak this menu when it's loaded swap out 
+    // "start service" or "stop service", depending on whether the service is currently running.
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu){
+        // Always call the superclass implementation to 
+        // provide standard items.
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, 0, R.string.menu_option_start, null);
+        menu.add(0, 1, R.string.menu_option_stop, null);
+        menu.add(0, 2, R.string.menu_option_add, null);
+        menu.add(0, 3, R.string.menu_option_delete, null);
+        menu.add(0, 4, R.string.menu_option_update, null);
+        
+        return true;
+    }
+    
+    // Toggle out start service/stop service depending on whether the service is running.
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu){
+        return true;
+    }
+    
+    // Handle our menu clicks.
+    @Override
+    public boolean onOptionsItemSelected(Menu.Item item){
+        super.onOptionsItemSelected(item);
+        
+        switch (item.getId()){
+            case 0:     // Start service
+                showAlert(null, "You clicked 'start'!", "ok", null, false, null);
+                break;
+            case 1:    // Stop service
+              showAlert(null, "You clicked stop!", "ok", null, false, null);
+              break;                    
+            case 2:     // Add Item
+                Intent addIntent = new Intent(AddRssItem.class);
+
+                // Use an ID so that if we create a "remove item" form we
+                // can tell which form is returning a value.
+                startActivityForResult(addIntent, ADD_ELEMENT_REQUEST); 
+                break; 
+            case 3:     // Delete item.
+                if(mRssList.hasFocus()){
+                  int currentSelectionIndex = mRssList.getSelectedItemIndex();
+
+                  // Create our content URI by adding the ID of the currently selected item using a 
+                  // convenience method.
+                  Long itemID = mAdap.getItemId(currentSelectionIndex);
+                  getContentResolver().delete(RssContentProvider.CONTENT_URI.addId(itemID), null);
+                }
+                break;
+            case 4:    // Update all
+                showAlert(null, "You clicked 'Update'!", "ok", null, false, null);
+                break;
+            default:
+                showAlert(null, "I have no idea what you clicked!", "ok", null, false, null);
+                break;
+        }
+        return true;
+    }
+    
+    // Called by the "Add RSS Item" floating screen when it closes.
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data){
+        if(resultCode == RESULT_OK){
+            switch (requestCode){
+                case ADD_ELEMENT_REQUEST:
+                    ContentValues vals = new ContentValues(4);
+                    vals.put(RssContentProvider.TITLE, data.getStringExtra(RssContentProvider.TITLE));
+                    vals.put(RssContentProvider.URL, data.getStringExtra(RssContentProvider.URL));
+                    vals.put(RssContentProvider.CONTENT, data.getStringExtra(RssContentProvider.CONTENT));
+                    vals.put(RssContentProvider.LAST_UPDATED, data.getIntExtra(RssContentProvider.LAST_UPDATED, 0));
+                    Uri uri = getContentResolver().insert(
+                            RssContentProvider.CONTENT_URI, 
+                            vals);
+                        if(uri != null){
+                            mRssList.setSelection(mRssList.getCount() - 1);
+                        }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+    
+    // Our private ArrayAdapter implementation that returns a bold TextView for 
+    // RSS items that are unread, or a normal TextView for items that have been read.
+    private class RssCursorAdapter extends SimpleCursorAdapter {
+        public RssCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to){
+            super(context, layout, c, from, to);
+        }
+        
+        // Here's our only important override--returning the list item.
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent){
+            TextView view = (TextView)super.getView(position, convertView, parent);
+            
+            if(view != null){
+                
+                // Now get the hasBeenRead value to determine the font.
+                int hasBeenReadColumnIndex = getCursor().getColumnIndex(
+                        RssContentProvider.HAS_BEEN_READ);
+                boolean hasBeenRead = (getCursor().getInt(hasBeenReadColumnIndex) == 1 ? true : false);
+                if(! hasBeenRead){
+                    Typeface type = view.getTypeface();
+                    view.setTypeface(Typeface.create(type, Typeface.BOLD_ITALIC));
+                }
+            }
+            return view;
+        } 
+    }
+}
+
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader5.java b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader5.java
new file mode 100644
index 0000000..0d59bfd
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/MyRssReader5.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Typeface;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+import java.util.logging.Logger;
+
+public class MyRssReader5 extends Activity implements OnItemSelectedListener {
+    
+    private ListView mRssList;
+    private Cursor mCur;
+    private RssCursorAdapter mAdap;
+    private WebView mWebView;
+    private static final int ADD_ELEMENT_REQUEST = 1;
+    private Logger mLogger = Logger.getLogger(this.getPackageName());
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+                                                                                                    //
+        // Load screen layout.
+        setContentView(R.layout.main_screen2);
+       
+        // Populate ArrayAdapter and bind it to ListView
+        mRssList = (ListView)findViewById(R.id.rssListView);
+        mRssList.setOnItemSelectedListener(this);
+        
+        mWebView = (WebView)findViewById(R.id.rssWebView);
+        
+        mCur = managedQuery(RssContentProvider.CONTENT_URI, // Query for all items.
+                       null, 
+                       null, 
+                       RssContentProvider.DEFAULT_SORT_ORDER);
+               
+        mAdap = new RssCursorAdapter(
+                this,
+                R.layout.list_element,                  // Our layout resource.
+                mCur, 
+                new String[]{RssContentProvider.TITLE}, // Columns to retrieve.
+                new int[]{R.id.list_item});             // IDs of widgets to display 
+        mRssList.setAdapter(mAdap);                    //      the corresponding column.
+        
+        // Set the last selected item.
+        // (icicle is only set if this is being restarted).
+        if(savedInstanceState != null && savedInstanceState.containsKey("lastIndexItem")){
+            mRssList.setSelection(savedInstanceState.getInteger("lastIndexItem"));
+        }
+    }
+
+//BEGIN_INCLUDE(5_4)
+    // Listener to listen for list selection changes, and send the new text to
+    // the web view.
+    public void onItemSelected(AdapterView parent, View v, int position, long id){
+        // Need to nest this in a try block because we get called sometimes
+        // with the index of a recently deleted item.
+        String content = "";
+        try{
+            content = mCur.getString(mCur.getColumnIndex(RssContentProvider.CONTENT));
+            mLogger.info("MyRssReader5 content string:" + content);
+        }
+        catch (Exception e){
+            // This method is sometimes called after a backing data item
+            // is deleted. In that case, we don't want to throw an error.
+            mLogger.warning("MyRssReader5.onItemSelected() couldn't get the content" +
+                            "from the cursor " + e.getMessage()); 
+        }
+        mWebView.loadData(content, "text/html", "utf-8");
+    }
+//END_INCLUDE(5_4)
+    
+    public void onNothingSelected(AdapterView parent){
+        mWebView.loadData("<html><body><p>No selection chosen</p></body></html>", "text/html", "utf-8");   
+    }
+   
+    // Store our state before we are potentially bumped from memory.
+    // We'd like to store the current ListView selection.
+    @Override
+    protected void onSaveInstanceState(Bundle outState){
+        int index = mRssList.getSelectedItemIndex();
+        if(index > -1){
+            outState.putInteger("lastIndexItem", index);
+        }
+    }
+  
+    // Add our initial menu options. We will tweak this menu when it's loaded swap out 
+    // "start service" or "stop service", depending on whether the service is currently running.
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu){
+        // Always call the superclass implementation to 
+        // provide standard items.
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, 0, R.string.menu_option_start, null);
+        menu.add(0, 1, R.string.menu_option_stop, null);
+        menu.add(0, 2, R.string.menu_option_add, null);
+        menu.add(0, 3, R.string.menu_option_delete, null);
+        menu.add(0, 4, R.string.menu_option_update, null);
+        
+        return true;
+    }
+    
+    // Toggle out start service/stop service depending on whether the service is running.
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu){
+        return true;
+    }
+    
+    // Handle our menu clicks.
+    @Override
+    public boolean onOptionsItemSelected(Menu.Item item){
+        super.onOptionsItemSelected(item);
+        
+        switch (item.getId()){
+            case 0:     // Start service
+                Intent basicStartIntent = new Intent(RssService.class);
+                startService(basicStartIntent);
+                break;
+            case 1:    // Stop service
+                Intent stopIntent = new Intent(RssService.class);
+                stopService(stopIntent);
+                break;
+            case 2:     // Add Item
+                Intent addIntent = new Intent(AddRssItem.class);
+                // Use an ID so that if we create a "remove item" form we
+                // can tell which form is returning a value.
+                startActivityForResult(addIntent, ADD_ELEMENT_REQUEST); 
+                break;                       
+            case 3:     // Delete item.
+                if(mRssList.hasFocus()){
+                    int currentSelectionIndex = mRssList.getSelectedItemIndex();
+                    mLogger.info("MyRssReader5.onOptionsItemSelected(): Deleting list member:" + 
+                            mRssList.getSelectedItemIndex());
+                    // Create our content URI by adding the ID of the currently selected item using a 
+                    // convenience method.
+                    Long itemID = mAdap.getItemId(currentSelectionIndex);
+                    getContentResolver().delete(RssContentProvider.CONTENT_URI.addId(itemID), null);
+                }
+                break;
+            case 4:     // Requery all
+                Bundle startupVals = new Bundle(1);
+                startupVals.putBoolean(RssService.REQUERY_KEY, true);
+                Intent requeryIntent = new Intent(RssService.class);
+                startService(requeryIntent, startupVals);
+                break;
+            default:
+                showAlert(null, "I have no idea what you clicked!", "ok", null, false, null);
+                break;
+        }
+        return true;
+    }
+    
+    // Called by the "Add RSS Item" floating screen when it closes.
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data){
+        if(resultCode == RESULT_OK){
+            switch (requestCode){
+                case ADD_ELEMENT_REQUEST:
+                      ContentValues vals = new ContentValues(5);
+                      vals.put(RssContentProvider.TITLE, data.getStringExtra(RssContentProvider.TITLE));
+                      vals.put(RssContentProvider.URL, data.getStringExtra(RssContentProvider.URL));
+                      vals.put(RssContentProvider.CONTENT, data.getStringExtra(RssContentProvider.CONTENT));
+                      vals.put(RssContentProvider.LAST_UPDATED, data.getIntExtra(RssContentProvider.LAST_UPDATED, 0));
+                      Uri uri = getContentResolver().insert(
+                              RssContentProvider.CONTENT_URI, 
+                              vals);
+                      if(uri != null){
+                          // Tell the service to requery the service, then set
+                          // it as the active selection.
+                          Bundle startupVals = new Bundle(1);
+                          startupVals.putString(RssService.RSS_URL, data.getStringExtra("URL"));
+                          Intent startIntent = new Intent(RssService.class);
+                          startIntent.putExtras(startupVals);
+                          startService(startIntent);
+                          mRssList.setSelection(mRssList.getCount() - 1);
+                      }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+    
+    // Our private ArrayAdapter implementation that returns a bold TextView for 
+    // RSS items that are unread, or a normal TextView for items that have been read.
+    private class RssCursorAdapter extends SimpleCursorAdapter {
+        public RssCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
+            super(context, layout, c, from, to);
+        }
+        
+        // Here's our only important override--returning the list item.
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent){
+            TextView view = (TextView)super.getView(position, convertView, parent);
+            
+            if(view != null){
+                
+                // Now get the hasBeenRead value to determine the font.
+                int hasBeenReadColumnIndex = getCursor().getColumnIndex(RssContentProvider.HAS_BEEN_READ);
+                boolean hasBeenRead = (getCursor().getInt(hasBeenReadColumnIndex) == 1 ? true : false);
+                if(! hasBeenRead){
+                    Typeface type = view.getTypeface();
+                    view.setTypeface(Typeface.create(type, Typeface.BOLD_ITALIC));
+                }
+            }
+            return view;
+        } 
+    }
+
+}
+
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/RssContentProvider.java b/samples/MySampleRss/src/com/example/codelab/rssexample/RssContentProvider.java
new file mode 100644
index 0000000..5d523dc
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/RssContentProvider.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.content.ContentProvider;
+import android.content.ContentProviderDatabaseHelper;
+import android.content.UriMatcher;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.content.ContentValues;
+import android.text.TextUtils;
+
+import java.util.logging.Logger;
+
+// Content Provider for RSS feed information. Each row describes a single
+// RSS feed. See the public static constants at the end of this class
+// to learn what each record contains.
+public class RssContentProvider extends ContentProvider {
+    private Logger mLogger = Logger.getLogger("com.example.codelab.rssexample");
+    private SQLiteDatabase mDb;
+    private DatabaseHelper mDbHelper = new DatabaseHelper();
+    private static final String DATABASE_NAME = "rssitems.db";
+    private static final String DATABASE_TABLE_NAME = "rssItems";
+    private static final int DB_VERSION = 1;
+    private static final int ALL_MESSAGES = 1;
+    private static final int SPECIFIC_MESSAGE = 2;
+
+    // Set up our URL matchers to help us determine what an
+    // incoming URI parameter is.
+    private static final UriMatcher URI_MATCHER;
+    static{
+        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+        URI_MATCHER.addURI("my_rss_item", "rssitem", ALL_MESSAGES);
+        URI_MATCHER.addURI("my_rss_item", "rssitem/#", SPECIFIC_MESSAGE);
+    }
+
+    // Here's the public URI used to query for RSS items.
+    public static final Uri CONTENT_URI = Uri.parse( "content://my_rss_item/rssitem");
+
+    // Here are our column name constants, used to query for field values.
+    public static final String ID = "_id";
+    public static final String URL = "url";
+    public static final String TITLE = "title";
+    public static final String HAS_BEEN_READ = "hasbeenread";
+    public static final String CONTENT = "rawcontent";
+    public static final String LAST_UPDATED = "lastupdated";
+    public static final String DEFAULT_SORT_ORDER = TITLE + " DESC";
+
+    // Database creation/version management helper.
+    // Create it statically because we don't need to have customized instances.
+    private static class DatabaseHelper extends ContentProviderDatabaseHelper{
+
+        @Override
+        public void onCreate(SQLiteDatabase db){
+            try{
+                String sql = "CREATE TABLE " + DATABASE_TABLE_NAME + "(" +
+                ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+                URL + " TEXT," +
+                TITLE + " TEXT," +
+                HAS_BEEN_READ + " BOOLEAN DEFAULT 0," +
+                CONTENT + " TEXT," +
+                LAST_UPDATED + " INTEGER DEFAULT 0);";
+                Logger.getLogger("com.example.codelab.rssexample").info("DatabaseHelper.onCreate(): SQL statement: " + sql);
+                db.execSQL(sql);
+                Logger.getLogger("com.example.codelab.rssexample").info("DatabaseHelper.onCreate(): Created a database");
+            } catch (SQLException e) {
+                Logger.getLogger("com.example.codelab.rssexample").warning("DatabaseHelper.onCreate(): Couldn't create a database!");
+            }
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
+            // Don't have any upgrades yet, so if this gets called for some reason we'll
+            // just drop the existing table, and recreate the database with the
+            // standard method.
+            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_NAME + ";");
+
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        // First we need to open the database. If this is our first time,
+        // the attempt to retrieve a database will throw
+        // FileNotFoundException, and we will then create the database.
+        final Context con = getContext();
+        try{
+            mDb = mDbHelper.openDatabase(getContext(), DATABASE_NAME, null, DB_VERSION);
+            mLogger.info("RssContentProvider.onCreate(): Opened a database");
+        } catch (Exception ex) {
+              return false;
+        }
+        if(mDb == null){
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    // Convert the URI into a custom MIME type.
+    // Our UriMatcher will parse the URI to decide whether the
+    // URI is for a single item or a list.
+    @Override
+    public String getType(Uri uri) {
+        switch (URI_MATCHER.match(uri)){
+            case ALL_MESSAGES:
+                return "vnd.android.cursor.dir/rssitem"; // List of items.
+            case SPECIFIC_MESSAGE:
+                return "vnd.android.cursor.item/rssitem";     // Specific item.
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String groupBy, String having, String sortOrder) {
+        // We won't bother checking the validity of params here, but you should!
+
+        // SQLiteQueryBuilder is the helper class that creates the
+        // proper SQL syntax for us.
+        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
+
+        // Set the table we're querying.
+        qBuilder.setTables(DATABASE_TABLE_NAME);
+
+        // If the query ends in a specific record number, we're
+        // being asked for a specific record, so set the
+        // WHERE clause in our query.
+        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
+            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
+        }
+
+        // Set sort order. If none specified, use default.
+        if(TextUtils.isEmpty(sortOrder)){
+            sortOrder = DEFAULT_SORT_ORDER;
+        }
+
+        // Make the query.
+        Cursor c = qBuilder.query(mDb,
+                projection,
+                selection,
+                selectionArgs,
+                groupBy,
+                having,
+                sortOrder);
+        c.setNotificationUri(getContext().getContentResolver(), uri);
+        return c;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String whereClause) {
+        // NOTE Argument checking code omitted. Check your parameters!
+        int updateCount = mDb.update(DATABASE_TABLE_NAME, values, whereClause);
+
+        // Notify any listeners and return the updated row count.
+        getContext().getContentResolver().notifyUpdate(uri, null);
+        return updateCount;
+    }
+
+    @Override
+    public Uri insert(Uri requestUri, ContentValues initialValues) {
+        // NOTE Argument checking code omitted. Check your parameters! Check that
+        // your row addition request succeeded!
+
+       long rowId = -1;
+       rowId = mDb.insert(DATABASE_TABLE_NAME, "rawcontent", initialValues);
+       Uri newUri = CONTENT_URI.addId(rowId);
+
+       // Notify any listeners and return the URI of the new row.
+       getContext().getContentResolver().notifyInsert(CONTENT_URI, null);
+       return newUri;
+    }
+
+    @Override
+    public int delete(Uri uri, String where) {
+        // NOTE Argument checking code omitted. Check your parameters!
+        int rowCount = mDb.delete(DATABASE_TABLE_NAME, ID + " = " + uri.getPathLeafId());
+
+        // Notify any listeners and return the deleted row count.
+        getContext().getContentResolver().notifyDelete(uri, null);
+        return rowCount;
+    }
+}
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/RssItem.java b/samples/MySampleRss/src/com/example/codelab/rssexample/RssItem.java
new file mode 100644
index 0000000..f13357d
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/RssItem.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import java.util.Date;
+
+// Custom class to hold an RSS item.
+public class RssItem{
+    public String url;
+    public String title;
+    public boolean hasBeenRead = false;
+    public String content;
+    public Date lastUpdated;
+    
+    public RssItem(String url, String title){
+        this.url = url;
+        this.title = title;
+    }
+    
+    @Override public String toString(){
+        return title;
+    }
+}
diff --git a/samples/MySampleRss/src/com/example/codelab/rssexample/RssService.java b/samples/MySampleRss/src/com/example/codelab/rssexample/RssService.java
new file mode 100644
index 0000000..e84f89d
--- /dev/null
+++ b/samples/MySampleRss/src/com/example/codelab/rssexample/RssService.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.codelab.rssexample;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Bundle;
+import android.database.Cursor;
+import android.content.ContentResolver;
+import android.os.Handler;
+import android.text.TextUtils;
+import java.io.BufferedReader;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.lang.StringBuilder;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.GregorianCalendar;
+import java.text.SimpleDateFormat;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.text.ParseException;
+    
+public class RssService extends Service implements Runnable{
+    private Logger mLogger = Logger.getLogger(this.getPackageName());
+    public static final String REQUERY_KEY = "Requery_All"; // Sent to tell us force a requery.
+    public static final String RSS_URL = "RSS_URL"; // Sent to tell us to requery a specific item.
+    private NotificationManager mNM;
+    private Cursor mCur;                        // RSS content provider cursor.
+    private GregorianCalendar mLastCheckedTime; // Time we last checked our feeds.
+    private final String LAST_CHECKED_PREFERENCE = "last_checked";
+    static final int UPDATE_FREQUENCY_IN_MINUTES = 60;
+    private Handler mHandler;           // Handler to trap our update reminders.
+    private final int NOTIFY_ID = 1;    // Identifies our service icon in the icon tray.
+    
+    @Override
+    protected void onCreate(){
+        // Display an icon to show that the service is running.
+        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+        Intent clickIntent = new Intent(Intent.ACTION_MAIN);
+        clickIntent.setClassName(MyRssReader5.class.getName());
+        Notification note = new Notification(this, R.drawable.rss_icon, "RSS Service",
+                clickIntent, null);
+        mNM.notify(NOTIFY_ID, note);
+        mHandler = new Handler();
+
+        // Create the intent that will be launched if the user clicks the 
+        // icon on the status bar. This will launch our RSS Reader app.
+        Intent intent = new Intent(MyRssReader.class);
+        
+        // Get a cursor over the RSS items.
+        ContentResolver rslv = getContentResolver();
+        mCur = rslv.query(RssContentProvider.CONTENT_URI, null, null, null, null);
+        
+        // Load last updated value.
+        // We store last updated value in preferences.
+        SharedPreferences pref = getSharedPreferences("", 0);
+        mLastCheckedTime = new GregorianCalendar();
+        mLastCheckedTime.setTimeInMillis(pref.getLong(LAST_CHECKED_PREFERENCE, 0));
+
+//BEGIN_INCLUDE(5_1)
+        // Need to run ourselves on a new thread, because 
+        // we will be making resource-intensive HTTP calls.
+        // Our run() method will check whether we need to requery
+        // our sources.
+        Thread thr = new Thread(null, this, "rss_service_thread");
+        thr.start();
+//END_INCLUDE(5_1)        
+        mLogger.info("RssService created");
+    }
+    
+//BEGIN_INCLUDE(5_3)
+    // A cheap way to pass a message to tell the service to requery.
+    @Override
+    protected void onStart(Intent intent, int startId){
+        super.onStart(startId, arguments);
+        Bundle arguments = intent.getExtras();
+        if(arguments != null) {
+            if(arguments.containsKey(REQUERY_KEY)) {
+                queryRssItems();
+            }
+            if(arguments.containsKey(RSS_URL)) {
+                // Typically called after adding a new RSS feed to the list.
+                queryItem(arguments.getString(RSS_URL));
+            }
+        }    
+    }
+//END_INCLUDE(5_3)
+    
+    // When the service is destroyed, get rid of our persistent icon.
+    @Override
+    protected void onDestroy(){
+      mNM.cancel(NOTIFY_ID);
+    }
+    
+    // Determines whether the next scheduled check time has passed.
+    // Loads this value from a stored preference. If it has (or if no
+    // previous value has been stored), it will requery all RSS feeds;
+    // otherwise, it will post a delayed reminder to check again after
+    // now - next_check_time milliseconds.
+    public void queryIfPeriodicRefreshRequired() {
+        GregorianCalendar nextCheckTime = new GregorianCalendar();
+        nextCheckTime = (GregorianCalendar) mLastCheckedTime.clone();
+        nextCheckTime.add(GregorianCalendar.MINUTE, UPDATE_FREQUENCY_IN_MINUTES);
+        mLogger.info("last checked time:" + mLastCheckedTime.toString() + "  Next checked time: " + nextCheckTime.toString());
+        
+        if(mLastCheckedTime.before(nextCheckTime)) {
+            queryRssItems();
+        } else {
+            // Post a message to query again when we get to the next check time.
+            long timeTillNextUpdate = mLastCheckedTime.getTimeInMillis() - GregorianCalendar.getInstance().getTimeInMillis();
+            mHandler.postDelayed(this, 1000 * 60 * UPDATE_FREQUENCY_IN_MINUTES);
+        }
+          
+    }
+
+    // Query all feeds. If the new feed has a newer pubDate than the previous,
+    // then update it.
+    void queryRssItems(){
+        mLogger.info("Querying Rss feeds...");
+ 
+        // The cursor might have gone stale. Requery to be sure.
+        // We need to call next() after a requery to get to the 
+        // first record.
+        mCur.requery();
+        while (mCur.next()){
+             // Get the URL for the feed from the cursor.
+             int urlColumnIndex = mCur.getColumnIndex(RssContentProvider.URL);
+             String url = mCur.getString(urlColumnIndex);
+             queryItem(url);
+        }
+        // Reset the global "last checked" time
+        mLastCheckedTime.setTimeInMillis(System.currentTimeMillis());
+      
+        // Post a message to query again in [update_frequency] minutes
+        mHandler.postDelayed(this, 1000 * 60 * UPDATE_FREQUENCY_IN_MINUTES);
+    }
+    
+    
+    // Query an individual RSS feed. Returns true if successful, false otherwise.
+    private boolean queryItem(String url) {
+        try {
+            URL wrappedUrl = new URL(url);
+            String rssFeed = readRss(wrappedUrl);
+            mLogger.info("RSS Feed " + url + ":\n " + rssFeed);
+            if(TextUtils.isEmpty(rssFeed)) {
+                return false;
+            }
+              
+            // Parse out the feed update date, and compare to the current version.
+            // If feed update time is newer, or zero (if never updated, for new 
+            // items), then update the content, date, and hasBeenRead fields.
+            // lastUpdated = <rss><channel><pubDate>value</pubDate></channel></rss>.
+            // If that value doesn't exist, the current date is used.
+            GregorianCalendar feedPubDate = parseRssDocPubDate(rssFeed);
+            GregorianCalendar lastUpdated = new GregorianCalendar();
+            int lastUpdatedColumnIndex = mCur.getColumnIndex(RssContentProvider.LAST_UPDATED);
+            lastUpdated.setTimeInMillis(mCur.getLong(lastUpdatedColumnIndex));
+            if(lastUpdated.getTimeInMillis() == 0 ||
+                lastUpdated.before(feedPubDate) && !TextUtils.isEmpty(rssFeed)) {
+                // Get column indices.
+                int contentColumnIndex = mCur.getColumnIndex(RssContentProvider.CONTENT);
+                int updatedColumnIndex = mCur.getColumnIndex(RssContentProvider.HAS_BEEN_READ);
+                 
+                // Update values.
+                mCur.updateString(contentColumnIndex, rssFeed);
+                mCur.updateLong(lastUpdatedColumnIndex, feedPubDate.getTimeInMillis());
+                mCur.updateInt(updatedColumnIndex, 0);
+                mCur.commitUpdates();
+            }
+        } catch (MalformedURLException ex) {
+              mLogger.warning("Error in queryItem: Bad url");
+              return false;
+        }
+        return true;
+    }  
+ 
+ // BEGIN_INCLUDE(5_2)    
+    // Get the <pubDate> content from a feed and return a 
+    // GregorianCalendar version of the date.
+    // If the element doesn't exist or otherwise can't be
+    // found, return a date of 0 to force a refresh.
+    private GregorianCalendar parseRssDocPubDate(String xml){
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.setTimeInMillis(0);
+        String patt ="<[\\s]*pubDate[\\s]*>(.+?)</pubDate[\\s]*>";
+        Pattern p = Pattern.compile(patt);
+        Matcher m = p.matcher(xml);
+        try {
+            if(m.find()) {
+                mLogger.info("pubDate: " + m.group());
+                SimpleDateFormat pubDate = new SimpleDateFormat();
+                cal.setTime(pubDate.parse(m.group(1)));
+            }
+       } catch(ParseException ex) {
+            mLogger.warning("parseRssDocPubDate couldn't find a <pubDate> tag. Returning default value.");
+       }
+        return cal;
+    }    
+    
+    // Read the submitted RSS page.
+    String readRss(URL url){
+      String html = "<html><body><h2>No data</h2></body></html>";
+      try {
+          mLogger.info("URL is:" + url.toString());
+          BufferedReader inStream =
+              new BufferedReader(new InputStreamReader(url.openStream()),
+                      1024);
+          String line;
+          StringBuilder rssFeed = new StringBuilder();
+          while ((line = inStream.readLine()) != null){
+              rssFeed.append(line);
+          }
+          html = rssFeed.toString();
+      } catch(IOException ex) {
+          mLogger.warning("Couldn't open an RSS stream");
+      }
+      return html;
+    }
+//END_INCLUDE(5_2)
+
+    // Callback we send to ourself to requery all feeds.
+    public void run() {
+        queryIfPeriodicRefreshRequired();
+    }
+    
+    // Required by Service. We won't implement it here, but need to 
+    // include this basic code.
+    @Override
+    public IBinder onBind(Intent intent){
+        return mBinder;
+    }
+
+    // This is the object that receives RPC calls from clients.See
+    // RemoteService for a more complete example.
+    private final IBinder mBinder = new Binder()  {
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
+            return super.onTransact(code, data, reply, flags);
+        }
+    };
+}
diff --git a/samples/NotePad/Android.mk b/samples/NotePad/Android.mk
new file mode 100644
index 0000000..7939212
--- /dev/null
+++ b/samples/NotePad/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 := NotePad
+
+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/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
new file mode 100644
index 0000000..5c56daf
--- /dev/null
+++ b/samples/NotePad/AndroidManifest.xml
@@ -0,0 +1,104 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.notepad"
+>
+    <application android:icon="@drawable/app_notes"
+        android:label="@string/app_name"
+    >
+        <provider android:name="NotePadProvider"
+            android:authorities="com.google.provider.NotePad"
+        />
+
+        <activity android:name="NotesList" android:label="@string/title_notes_list">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.EDIT" />
+                <action android:name="android.intent.action.PICK" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.GET_CONTENT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name="NoteEditor"
+            android:theme="@android:style/Theme.Light"
+            android:label="@string/title_note"
+            android:screenOrientation="sensor"
+            android:configChanges="keyboardHidden|orientation"
+        >
+            <!-- This filter says that we can view or edit the data of
+                 a single note -->
+            <intent-filter android:label="@string/resolve_edit">
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.EDIT" />
+                <action android:name="com.android.notepad.action.EDIT_NOTE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
+            </intent-filter>
+
+            <!-- This filter says that we can create a new note inside
+                 of a directory of notes. -->
+            <intent-filter>
+                <action android:name="android.intent.action.INSERT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
+            </intent-filter>
+
+        </activity>
+        
+		<activity android:name="TitleEditor" android:label="@string/title_edit_title"
+				android:theme="@android:style/Theme.Dialog"
+                android:windowSoftInputMode="stateVisible">
+            <!-- This activity implements an alternative action that can be
+                 performed on notes: editing their title.  It can be used as
+                 a default operation if the user invokes this action, and is
+                 available as an alternative action for any note data. -->
+            <intent-filter android:label="@string/resolve_title">
+                <!-- This is the action we perform.  It is a custom action we
+                     define for our application, not a generic VIEW or EDIT
+                     action since we are not a general note viewer/editor. -->
+                <action android:name="com.android.notepad.action.EDIT_TITLE" />
+                <!-- DEFAULT: execute if being directly invoked. -->
+                <category android:name="android.intent.category.DEFAULT" />
+                <!-- ALTERNATIVE: show as an alternative action when the user is
+                     working with this type of data. -->
+                <category android:name="android.intent.category.ALTERNATIVE" />
+                <!-- SELECTED_ALTERNATIVE: show as an alternative action the user
+                     can perform when selecting this type of data. -->
+                <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
+                <!-- This is the data type we operate on. -->
+                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
+            </intent-filter>
+        </activity>
+        
+    </application>
+</manifest>
+
diff --git a/samples/NotePad/_index.html b/samples/NotePad/_index.html
new file mode 100644
index 0000000..2a18969
--- /dev/null
+++ b/samples/NotePad/_index.html
@@ -0,0 +1,12 @@
+<p>A simple note pad application.
+It demonstrates...
+<ul> 
+<li>using views
+<li>accessing a database
+<li>using an intent to open a new window
+<li>managing activity lifecycle
+<li>and many other goodies...
+</ul>
+</p>
+<img alt="Note Pad Example" class="gallery"  src="sample_notepad.png" >
+<img alt="Note Pad Example" class="gallery"  src="sample_note.png"  >
diff --git a/samples/NotePad/res/drawable/app_notes.png b/samples/NotePad/res/drawable/app_notes.png
new file mode 100644
index 0000000..0479138
--- /dev/null
+++ b/samples/NotePad/res/drawable/app_notes.png
Binary files differ
diff --git a/samples/NotePad/res/layout/note_editor.xml b/samples/NotePad/res/layout/note_editor.xml
new file mode 100644
index 0000000..c54a963
--- /dev/null
+++ b/samples/NotePad/res/layout/note_editor.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.example.android.notepad.NoteEditor$LinedEditText"
+    android:id="@+id/note"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="@android:color/transparent"
+    android:padding="5dip"
+    android:scrollbars="vertical"
+    android:fadingEdge="vertical"
+    android:gravity="top"
+    android:textSize="22sp"
+    android:capitalize="sentences"
+/>
diff --git a/samples/NotePad/res/layout/noteslist_item.xml b/samples/NotePad/res/layout/noteslist_item.xml
new file mode 100644
index 0000000..b167734
--- /dev/null
+++ b/samples/NotePad/res/layout/noteslist_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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="@android:id/text1"
+    android:layout_width="fill_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:textAppearance="?android:attr/textAppearanceLarge"
+    android:gravity="center_vertical"
+    android:paddingLeft="5dip"
+    android:singleLine="true"
+/>
diff --git a/samples/NotePad/res/layout/title_editor.xml b/samples/NotePad/res/layout/title_editor.xml
new file mode 100644
index 0000000..3593ec6
--- /dev/null
+++ b/samples/NotePad/res/layout/title_editor.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+  	android:layout_width="wrap_content" 
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingLeft="6dip"
+    android:paddingRight="6dip"
+    android:paddingBottom="3dip">
+   					  
+    <EditText android:id="@+id/title" 
+        android:maxLines="1" 
+        android:layout_marginTop="2dip"
+        android:layout_width="wrap_content"
+      	android:ems="25"
+        android:layout_height="wrap_content" 
+        android:autoText="true"
+        android:capitalize="sentences"
+        android:scrollHorizontally="true" />
+   		
+    <Button android:id="@+id/ok"
+        android:layout_width="wrap_content" 
+        android:layout_height="wrap_content" 
+        android:layout_gravity="right"
+        android:text="@string/button_ok" />
+   		
+</LinearLayout>
diff --git a/samples/NotePad/res/values/strings.xml b/samples/NotePad/res/values/strings.xml
new file mode 100644
index 0000000..b4bf671
--- /dev/null
+++ b/samples/NotePad/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?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>
+    <string name="menu_delete">Delete</string>
+    <string name="menu_insert">Add note</string>
+    <string name="menu_revert">Revert</string>
+    <string name="menu_discard">Discard</string>
+
+    <string name="resolve_edit">Edit note</string>
+    <string name="resolve_title">Edit title</string>  
+
+    <string name="title_create">Create note</string>
+    <string name="title_edit">Edit note</string>
+	<string name="title_notes_list">Note pad</string>   
+	<string name="title_note">Note</string>  
+	<string name="title_edit_title">Note title:</string>  
+	
+	<string name="app_name">Note Pad</string>  
+	
+	<string name="button_ok">OK</string>  
+	
+	<string name="error_title">Error</string>
+	<string name="error_message">Error loading note</string>
+</resources>
diff --git a/samples/NotePad/sample_note.png b/samples/NotePad/sample_note.png
new file mode 100644
index 0000000..cea1a08
--- /dev/null
+++ b/samples/NotePad/sample_note.png
Binary files differ
diff --git a/samples/NotePad/sample_notepad.png b/samples/NotePad/sample_notepad.png
new file mode 100644
index 0000000..c498847
--- /dev/null
+++ b/samples/NotePad/sample_notepad.png
Binary files differ
diff --git a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
new file mode 100644
index 0000000..e45efd8
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.EditText;
+
+/**
+ * A generic activity for editing a note in a database.  This can be used
+ * either to simply view a note {@link Intent#ACTION_VIEW}, view and edit a note
+ * {@link Intent#ACTION_EDIT}, or create a new note {@link Intent#ACTION_INSERT}.  
+ */
+public class NoteEditor extends Activity {
+    private static final String TAG = "Notes";
+
+    /**
+     * Standard projection for the interesting columns of a normal note.
+     */
+    private static final String[] PROJECTION = new String[] {
+            Notes._ID, // 0
+            Notes.NOTE, // 1
+    };
+    /** The index of the note column */
+    private static final int COLUMN_INDEX_NOTE = 1;
+    
+    // This is our state data that is stored when freezing.
+    private static final String ORIGINAL_CONTENT = "origContent";
+
+    // Identifiers for our menu items.
+    private static final int REVERT_ID = Menu.FIRST;
+    private static final int DISCARD_ID = Menu.FIRST + 1;
+    private static final int DELETE_ID = Menu.FIRST + 2;
+
+    // The different distinct states the activity can be run in.
+    private static final int STATE_EDIT = 0;
+    private static final int STATE_INSERT = 1;
+
+    private int mState;
+    private boolean mNoteOnly = false;
+    private Uri mUri;
+    private Cursor mCursor;
+    private EditText mText;
+    private String mOriginalContent;
+
+    /**
+     * A custom EditText that draws lines between each line of text that is displayed.
+     */
+    public static class LinedEditText extends EditText {
+        private Rect mRect;
+        private Paint mPaint;
+
+        // we need this constructor for LayoutInflater
+        public LinedEditText(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            
+            mRect = new Rect();
+            mPaint = new Paint();
+            mPaint.setStyle(Paint.Style.STROKE);
+            mPaint.setColor(0x800000FF);
+        }
+        
+        @Override
+        protected void onDraw(Canvas canvas) {
+            int count = getLineCount();
+            Rect r = mRect;
+            Paint paint = mPaint;
+
+            for (int i = 0; i < count; i++) {
+                int baseline = getLineBounds(i, r);
+
+                canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
+            }
+
+            super.onDraw(canvas);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final Intent intent = getIntent();
+
+        // Do some setup based on the action being performed.
+
+        final String action = intent.getAction();
+        if (Intent.ACTION_EDIT.equals(action)) {
+            // Requested to edit: set that state, and the data being edited.
+            mState = STATE_EDIT;
+            mUri = intent.getData();
+        } else if (Intent.ACTION_INSERT.equals(action)) {
+            // Requested to insert: set that state, and create a new entry
+            // in the container.
+            mState = STATE_INSERT;
+            mUri = getContentResolver().insert(intent.getData(), null);
+
+            // If we were unable to create a new note, then just finish
+            // this activity.  A RESULT_CANCELED will be sent back to the
+            // original activity if they requested a result.
+            if (mUri == null) {
+                Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
+                finish();
+                return;
+            }
+
+            // The new entry was created, so assume all will end well and
+            // set the result to be returned.
+            setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
+
+        } else {
+            // Whoops, unknown action!  Bail.
+            Log.e(TAG, "Unknown action, exiting");
+            finish();
+            return;
+        }
+
+        // Set the layout for this activity.  You can find it in res/layout/note_editor.xml
+        setContentView(R.layout.note_editor);
+        
+        // The text view for our note, identified by its ID in the XML file.
+        mText = (EditText) findViewById(R.id.note);
+
+        // Get the note!
+        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
+
+        // If an instance of this activity had previously stopped, we can
+        // get the original text it started with.
+        if (savedInstanceState != null) {
+            mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // If we didn't have any trouble retrieving the data, it is now
+        // time to get at the stuff.
+        if (mCursor != null) {
+            // Make sure we are at the one and only row in the cursor.
+            mCursor.moveToFirst();
+
+            // Modify our overall title depending on the mode we are running in.
+            if (mState == STATE_EDIT) {
+                setTitle(getText(R.string.title_edit));
+            } else if (mState == STATE_INSERT) {
+                setTitle(getText(R.string.title_create));
+            }
+
+            // This is a little tricky: we may be resumed after previously being
+            // paused/stopped.  We want to put the new text in the text view,
+            // but leave the user where they were (retain the cursor position
+            // etc).  This version of setText does that for us.
+            String note = mCursor.getString(COLUMN_INDEX_NOTE);
+            mText.setTextKeepState(note);
+            
+            // If we hadn't previously retrieved the original text, do so
+            // now.  This allows the user to revert their changes.
+            if (mOriginalContent == null) {
+                mOriginalContent = note;
+            }
+
+        } else {
+            setTitle(getText(R.string.error_title));
+            mText.setText(getText(R.string.error_message));
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        // Save away the original text, so we still have it if the activity
+        // needs to be killed while paused.
+        outState.putString(ORIGINAL_CONTENT, mOriginalContent);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // The user is going somewhere else, so make sure their current
+        // changes are safely saved away in the provider.  We don't need
+        // to do this if only editing.
+        if (mCursor != null) {
+            String text = mText.getText().toString();
+            int length = text.length();
+
+            // If this activity is finished, and there is no text, then we
+            // do something a little special: simply delete the note entry.
+            // Note that we do this both for editing and inserting...  it
+            // would be reasonable to only do it when inserting.
+            if (isFinishing() && (length == 0) && !mNoteOnly) {
+                setResult(RESULT_CANCELED);
+                deleteNote();
+
+            // Get out updates into the provider.
+            } else {
+                ContentValues values = new ContentValues();
+
+                // This stuff is only done when working with a full-fledged note.
+                if (!mNoteOnly) {
+                    // Bump the modification time to now.
+                    values.put(Notes.MODIFIED_DATE, System.currentTimeMillis());
+
+                    // If we are creating a new note, then we want to also create
+                    // an initial title for it.
+                    if (mState == STATE_INSERT) {
+                        String title = text.substring(0, Math.min(30, length));
+                        if (length > 30) {
+                            int lastSpace = title.lastIndexOf(' ');
+                            if (lastSpace > 0) {
+                                title = title.substring(0, lastSpace);
+                            }
+                        }
+                        values.put(Notes.TITLE, title);
+                    }
+                }
+
+                // Write our text back into the provider.
+                values.put(Notes.NOTE, text);
+
+                // Commit all of our changes to persistent storage. When the update completes
+                // the content provider will notify the cursor of the change, which will
+                // cause the UI to be updated.
+                getContentResolver().update(mUri, values, null, null);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        // Build the menus that are shown when editing.
+        if (mState == STATE_EDIT) {
+            menu.add(0, REVERT_ID, 0, R.string.menu_revert)
+                    .setShortcut('0', 'r')
+                    .setIcon(android.R.drawable.ic_menu_revert);
+            if (!mNoteOnly) {
+                menu.add(0, DELETE_ID, 0, R.string.menu_delete)
+                        .setShortcut('1', 'd')
+                        .setIcon(android.R.drawable.ic_menu_delete);
+            }
+
+        // Build the menus that are shown when inserting.
+        } else {
+            menu.add(0, DISCARD_ID, 0, R.string.menu_discard)
+                    .setShortcut('0', 'd')
+                    .setIcon(android.R.drawable.ic_menu_delete);
+        }
+
+        // If we are working on a full note, then append to the
+        // menu items for any other activities that can do stuff with it
+        // as well.  This does a query on the system for any activities that
+        // implement the ALTERNATIVE_ACTION for our data, adding a menu item
+        // for each one that is found.
+        if (!mNoteOnly) {
+            Intent intent = new Intent(null, getIntent().getData());
+            intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
+                    new ComponentName(this, NoteEditor.class), null, intent, 0, null);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle all of the possible menu actions.
+        switch (item.getItemId()) {
+        case DELETE_ID:
+            deleteNote();
+            finish();
+            break;
+        case DISCARD_ID:
+            cancelNote();
+            break;
+        case REVERT_ID:
+            cancelNote();
+            break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /**
+     * Take care of canceling work on a note.  Deletes the note if we
+     * had created it, otherwise reverts to the original text.
+     */
+    private final void cancelNote() {
+        if (mCursor != null) {
+            if (mState == STATE_EDIT) {
+                // Put the original note text back into the database
+                mCursor.close();
+                mCursor = null;
+                ContentValues values = new ContentValues();
+                values.put(Notes.NOTE, mOriginalContent);
+                getContentResolver().update(mUri, values, null, null);
+            } else if (mState == STATE_INSERT) {
+                // We inserted an empty note, make sure to delete it
+                deleteNote();
+            }
+        }
+        setResult(RESULT_CANCELED);
+        finish();
+    }
+
+    /**
+     * Take care of deleting a note.  Simply deletes the entry.
+     */
+    private final void deleteNote() {
+        if (mCursor != null) {
+            mCursor.close();
+            mCursor = null;
+            getContentResolver().delete(mUri, null, null);
+            mText.setText("");
+        }
+    }
+}
diff --git a/samples/NotePad/src/com/example/android/notepad/NotePad.java b/samples/NotePad/src/com/example/android/notepad/NotePad.java
new file mode 100644
index 0000000..25be23e
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NotePad.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Convenience definitions for NotePadProvider
+ */
+public final class NotePad {
+    public static final String AUTHORITY = "com.google.provider.NotePad";
+
+    // This class cannot be instantiated
+    private NotePad() {}
+    
+    /**
+     * Notes table
+     */
+    public static final class Notes implements BaseColumns {
+        // This class cannot be instantiated
+        private Notes() {}
+
+        /**
+         * The content:// style URL for this table
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
+
+        /**
+         * The MIME type of {@link #CONTENT_URI} providing a directory of notes.
+         */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";
+
+        /**
+         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single note.
+         */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";
+
+        /**
+         * The default sort order for this table
+         */
+        public static final String DEFAULT_SORT_ORDER = "modified DESC";
+
+        /**
+         * The title of the note
+         * <P>Type: TEXT</P>
+         */
+        public static final String TITLE = "title";
+
+        /**
+         * The note itself
+         * <P>Type: TEXT</P>
+         */
+        public static final String NOTE = "note";
+
+        /**
+         * The timestamp for when the note was created
+         * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
+         */
+        public static final String CREATED_DATE = "created";
+
+        /**
+         * The timestamp for when the note was last modified
+         * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
+         */
+        public static final String MODIFIED_DATE = "modified";
+    }
+}
diff --git a/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
new file mode 100644
index 0000000..f1d3fdc
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Provides access to a database of notes. Each note has a title, the note
+ * itself, a creation date and a modified data.
+ */
+public class NotePadProvider extends ContentProvider {
+
+    private static final String TAG = "NotePadProvider";
+
+    private static final String DATABASE_NAME = "note_pad.db";
+    private static final int DATABASE_VERSION = 2;
+    private static final String NOTES_TABLE_NAME = "notes";
+
+    private static HashMap<String, String> sNotesProjectionMap;
+
+    private static final int NOTES = 1;
+    private static final int NOTE_ID = 2;
+
+    private static final UriMatcher sUriMatcher;
+
+    /**
+     * This class helps open, create, and upgrade the database file.
+     */
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+
+        DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
+                    + Notes._ID + " INTEGER PRIMARY KEY,"
+                    + Notes.TITLE + " TEXT,"
+                    + Notes.NOTE + " TEXT,"
+                    + Notes.CREATED_DATE + " INTEGER,"
+                    + Notes.MODIFIED_DATE + " INTEGER"
+                    + ");");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                    + newVersion + ", which will destroy all old data");
+            db.execSQL("DROP TABLE IF EXISTS notes");
+            onCreate(db);
+        }
+    }
+
+    private DatabaseHelper mOpenHelper;
+
+    @Override
+    public boolean onCreate() {
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            qb.setTables(NOTES_TABLE_NAME);
+            qb.setProjectionMap(sNotesProjectionMap);
+            break;
+
+        case NOTE_ID:
+            qb.setTables(NOTES_TABLE_NAME);
+            qb.setProjectionMap(sNotesProjectionMap);
+            qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        // If no sort order is specified use the default
+        String orderBy;
+        if (TextUtils.isEmpty(sortOrder)) {
+            orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
+        } else {
+            orderBy = sortOrder;
+        }
+
+        // Get the database and run the query
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
+
+        // Tell the cursor what uri to watch, so it knows when its source data changes
+        c.setNotificationUri(getContext().getContentResolver(), uri);
+        return c;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            return Notes.CONTENT_TYPE;
+
+        case NOTE_ID:
+            return Notes.CONTENT_ITEM_TYPE;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+        // Validate the requested uri
+        if (sUriMatcher.match(uri) != NOTES) {
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        ContentValues values;
+        if (initialValues != null) {
+            values = new ContentValues(initialValues);
+        } else {
+            values = new ContentValues();
+        }
+
+        Long now = Long.valueOf(System.currentTimeMillis());
+
+        // Make sure that the fields are all set
+        if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {
+            values.put(NotePad.Notes.CREATED_DATE, now);
+        }
+
+        if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
+            values.put(NotePad.Notes.MODIFIED_DATE, now);
+        }
+
+        if (values.containsKey(NotePad.Notes.TITLE) == false) {
+            Resources r = Resources.getSystem();
+            values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
+        }
+
+        if (values.containsKey(NotePad.Notes.NOTE) == false) {
+            values.put(NotePad.Notes.NOTE, "");
+        }
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
+        if (rowId > 0) {
+            Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
+            getContext().getContentResolver().notifyChange(noteUri, null);
+            return noteUri;
+        }
+
+        throw new SQLException("Failed to insert row into " + uri);
+    }
+
+    @Override
+    public int delete(Uri uri, String where, String[] whereArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count;
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
+            break;
+
+        case NOTE_ID:
+            String noteId = uri.getPathSegments().get(1);
+            count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId
+                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count;
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);
+            break;
+
+        case NOTE_ID:
+            String noteId = uri.getPathSegments().get(1);
+            count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId
+                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    static {
+        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
+
+        sNotesProjectionMap = new HashMap<String, String>();
+        sNotesProjectionMap.put(Notes._ID, Notes._ID);
+        sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
+        sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
+        sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);
+        sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);
+    }
+}
diff --git a/samples/NotePad/src/com/example/android/notepad/NotesList.java b/samples/NotePad/src/com/example/android/notepad/NotesList.java
new file mode 100644
index 0000000..ceaaa3c
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NotesList.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.app.ListActivity;
+import android.content.ComponentName;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+
+/**
+ * Displays a list of notes. Will display notes from the {@link Uri}
+ * provided in the intent if there is one, otherwise defaults to displaying the
+ * contents of the {@link NotePadProvider}
+ */
+public class NotesList extends ListActivity {
+    private static final String TAG = "NotesList";
+
+    // Menu item ids
+    public static final int MENU_ITEM_DELETE = Menu.FIRST;
+    public static final int MENU_ITEM_INSERT = Menu.FIRST + 1;
+
+    /**
+     * The columns we are interested in from the database
+     */
+    private static final String[] PROJECTION = new String[] {
+            Notes._ID, // 0
+            Notes.TITLE, // 1
+    };
+
+    /** The index of the title column */
+    private static final int COLUMN_INDEX_TITLE = 1;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
+
+        // If no data was given in the intent (because we were started
+        // as a MAIN activity), then use our default content provider.
+        Intent intent = getIntent();
+        if (intent.getData() == null) {
+            intent.setData(Notes.CONTENT_URI);
+        }
+
+        // Inform the list we provide context menus for items
+        getListView().setOnCreateContextMenuListener(this);
+        
+        // Perform a managed query. The Activity will handle closing and requerying the cursor
+        // when needed.
+        Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
+                Notes.DEFAULT_SORT_ORDER);
+
+        // Used to map notes entries from the database to views
+        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
+                new String[] { Notes.TITLE }, new int[] { android.R.id.text1 });
+        setListAdapter(adapter);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        // This is our one standard application action -- inserting a
+        // new note into the list.
+        menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
+                .setShortcut('3', 'a')
+                .setIcon(android.R.drawable.ic_menu_add);
+
+        // Generate any additional actions that can be performed on the
+        // overall list.  In a normal install, there are no additional
+        // actions found here, but this allows other applications to extend
+        // our menu with their own actions.
+        Intent intent = new Intent(null, getIntent().getData());
+        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
+                new ComponentName(this, NotesList.class), null, intent, 0, null);
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        final boolean haveItems = getListAdapter().getCount() > 0;
+
+        // If there are any notes in the list (which implies that one of
+        // them is selected), then we need to generate the actions that
+        // can be performed on the current selection.  This will be a combination
+        // of our own specific actions along with any extensions that can be
+        // found.
+        if (haveItems) {
+            // This is the selected item.
+            Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
+
+            // Build menu...  always starts with the EDIT action...
+            Intent[] specifics = new Intent[1];
+            specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
+            MenuItem[] items = new MenuItem[1];
+
+            // ... is followed by whatever other actions are available...
+            Intent intent = new Intent(null, uri);
+            intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
+                    items);
+
+            // Give a shortcut to the edit action.
+            if (items[0] != null) {
+                items[0].setShortcut('1', 'e');
+            }
+        } else {
+            menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case MENU_ITEM_INSERT:
+            // Launch activity to insert a new item
+            startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return;
+        }
+
+        Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+        if (cursor == null) {
+            // For some reason the requested item isn't available, do nothing
+            return;
+        }
+
+        // Setup the menu header
+        menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
+
+        // Add a menu item to delete the note
+        menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);
+    }
+        
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return false;
+        }
+
+        switch (item.getItemId()) {
+            case MENU_ITEM_DELETE: {
+                // Delete the note that the context menu is for
+                Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
+                getContentResolver().delete(noteUri, null, null);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
+        
+        String action = getIntent().getAction();
+        if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
+            // The caller is waiting for us to return a note selected by
+            // the user.  The have clicked on one, so return it now.
+            setResult(RESULT_OK, new Intent().setData(uri));
+        } else {
+            // Launch activity to view/edit the currently selected item
+            startActivity(new Intent(Intent.ACTION_EDIT, uri));
+        }
+    }
+}
diff --git a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
new file mode 100644
index 0000000..50d38e5
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * An activity that will edit the title of a note. Displays a floating
+ * window with a text field.
+ */
+public class TitleEditor extends Activity implements View.OnClickListener {
+
+    /**
+     * This is a special intent action that means "edit the title of a note".
+     */
+    public static final String EDIT_TITLE_ACTION = "com.android.notepad.action.EDIT_TITLE";
+
+    /**
+     * An array of the columns we are interested in.
+     */
+    private static final String[] PROJECTION = new String[] {
+            NotePad.Notes._ID, // 0
+            NotePad.Notes.TITLE, // 1
+    };
+    /** Index of the title column */
+    private static final int COLUMN_INDEX_TITLE = 1;
+
+    /**
+     * Cursor which will provide access to the note whose title we are editing.
+     */
+    private Cursor mCursor;
+
+    /**
+     * The EditText field from our UI. Keep track of this so we can extract the
+     * text when we are finished.
+     */
+    private EditText mText;
+
+    /**
+     * The content URI to the note that's being edited.
+     */
+    private Uri mUri;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.title_editor);
+
+        // Get the uri of the note whose title we want to edit
+        mUri = getIntent().getData();
+
+        // Get a cursor to access the note
+        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
+
+        // Set up click handlers for the text field and button
+        mText = (EditText) this.findViewById(R.id.title);
+        mText.setOnClickListener(this);
+        
+        Button b = (Button) findViewById(R.id.ok);
+        b.setOnClickListener(this);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Initialize the text with the title column from the cursor
+        if (mCursor != null) {
+            mCursor.moveToFirst();
+            mText.setText(mCursor.getString(COLUMN_INDEX_TITLE));
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        if (mCursor != null) {
+            // Write the title back to the note 
+            ContentValues values = new ContentValues();
+            values.put(Notes.TITLE, mText.getText().toString());
+            getContentResolver().update(mUri, values, null, null);
+        }
+    }
+
+    public void onClick(View v) {
+        // When the user clicks, just finish this activity.
+        // onPause will be called, and we save our data there.
+        finish();
+    }
+}
diff --git a/samples/NotePad/src/com/google/provider/NotePad.java b/samples/NotePad/src/com/google/provider/NotePad.java
new file mode 100644
index 0000000..f8de69b
--- /dev/null
+++ b/samples/NotePad/src/com/google/provider/NotePad.java
@@ -0,0 +1,65 @@
+/* 
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.provider;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Convenience definitions for NotePadProvider
+ */
+public final class NotePad {
+    /**
+     * Notes table
+     */
+    public static final class Notes implements BaseColumns {
+        /**
+         * The content:// style URL for this table
+         */
+        public static final Uri CONTENT_URI
+                = Uri.parse("content://com.google.provider.NotePad/notes");
+
+        /**
+         * The default sort order for this table
+         */
+        public static final String DEFAULT_SORT_ORDER = "modified DESC";
+
+        /**
+         * The title of the note
+         * <P>Type: TEXT</P>
+         */
+        public static final String TITLE = "title";
+
+        /**
+         * The note itself
+         * <P>Type: TEXT</P>
+         */
+        public static final String NOTE = "note";
+
+        /**
+         * The timestamp for when the note was created
+         * <P>Type: INTEGER (long)</P>
+         */
+        public static final String CREATED_DATE = "created";
+
+        /**
+         * The timestamp for when the note was last modified
+         * <P>Type: INTEGER (long)</P>
+         */
+        public static final String MODIFIED_DATE = "modified";
+    }
+}
diff --git a/samples/NotePad/tests/Android.mk b/samples/NotePad/tests/Android.mk
new file mode 100644
index 0000000..43efafc
--- /dev/null
+++ b/samples/NotePad/tests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := NotePadTests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_INSTRUMENTATION_FOR := NotePad
+
+include $(BUILD_PACKAGE)
diff --git a/samples/NotePad/tests/AndroidManifest.xml b/samples/NotePad/tests/AndroidManifest.xml
new file mode 100644
index 0000000..afd502b
--- /dev/null
+++ b/samples/NotePad/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.notepad.tests">
+    
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+  <instrumentation android:name="android.test.InstrumentationTestRunner"
+      android:targetPackage="com.example.android.notepad"
+      android:label="NotePad sample tests">
+  </instrumentation>  
+  
+</manifest>
diff --git a/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
new file mode 100644
index 0000000..452c599
--- /dev/null
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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.notepad;
+
+import android.test.ActivityInstrumentationTestCase;
+
+import com.example.android.notepad.NotesList;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class NotePadTest extends ActivityInstrumentationTestCase<NotesList> {
+
+  public NotePadTest() {
+      super("com.example.android.notepad", NotesList.class);
+  }
+
+}
diff --git a/samples/PlatformLibrary/Android.mk b/samples/PlatformLibrary/Android.mk
new file mode 100644
index 0000000..afb54a2
--- /dev/null
+++ b/samples/PlatformLibrary/Android.mk
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2008 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.
+#
+
+# This makefile shows how to build your own shared library that can be
+# shipped on the system of a phone, and included additional examples of
+# including JNI code with the library and writing client applications against it.
+
+LOCAL_PATH := $(call my-dir)
+
+# the library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# This is the target being built.
+LOCAL_MODULE:= com.example.android.platform_library
+
+# Only compile source java files for the platform library.
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
+
+include $(BUILD_JAVA_LIBRARY)
+
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := com.example.android.platform_library.xml
+
+LOCAL_MODULE_TAGS := samples
+
+LOCAL_MODULE_CLASS := ETC
+
+# This will install the file in /system/etc/permissions
+#
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
+# ============================================================
+
+# Also build all of the sub-targets under this one: the library's
+# associated JNI code, and a sample client of the library.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/PlatformLibrary/README.txt b/samples/PlatformLibrary/README.txt
new file mode 100644
index 0000000..5ce9d2f
--- /dev/null
+++ b/samples/PlatformLibrary/README.txt
@@ -0,0 +1,74 @@
+Platform Library Example
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+This directory contains a full example of writing your own Android platform
+shared library, without changing the Android framework.  It also shows how to
+write JNI code for incorporating native code into the library, and a client
+application that uses the library.
+
+This example is ONLY for people working with the open source platform to
+create a system image that will be delivered on a device which will include
+a custom library as shown here.  It can not be used to create a third party
+shared library, which is not currently supported in Android.
+
+To declare your library to the framework, you must place a file with a .xml
+extension in the /system/etc/permissions directory with the following contents:
+
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+    <library name="com.example.android.platform_library"
+            file="/system/framework/com.example.android.platform_library.jar"/>
+</permissions>
+
+There are three major parts of this example, supplying three distinct
+build targets and corresponding build outputs:
+
+
+com.example.android.platform_library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The top-level Android.mk defines the rules to build the shared library itself,
+whose target is "com.example.android.platform_library".  The code for this
+library lives under java/.
+
+Note that the product for this library is a raw .jar file, NOT a .apk, which
+means there is no manifest or resources associated with the library.
+Unfortunately this means that if you need any resources for the library, such
+as drawables or layout files, you will need to add these to the core framework
+resources under frameworks/base/res.  Please make sure when doing this that
+you do not make any of these resources public, they should not become part of
+the Android API.  In the future we will allow shared libraries to have their
+own resources.
+
+Other than that, the library is very straight-forward, and you can write
+basically whatever code you want.  You can also put code in other Java
+namespaces -- the namespace given in the <library> tag above is just the
+public unique name by which clients will link to your library, but once this
+link happens all of the Java namespaces in that library will be available
+to the client.
+
+
+libplatform_library_jni
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This is an optional example of how to write JNI code associated with a
+shared library.  This code lives under jni/.  The jni/Android.mk file defines
+the rules for building the final .so in which the code lives.  This example
+provides everything needed to hook up the native code with the Java library
+and call through to it, plus a very simple JNI call.
+
+
+PlatformLibraryClient
+~~~~~~~~~~~~~~~~~~~~~
+
+This shows an example of how you can write client applications for your new
+shared library.  This code lives under client/.  Note that the example is
+simply a regular Android .apk, like all of the other .apks created by the
+build system.  The only two special things needed to use your library are:
+
+- A LOCAL_JAVA_LIBRARIES line in the Android.mk to have the build system link
+against your shared library.
+
+- A <uses-library> line in the AndroidManifest.xml to have the runtime load
+your library into the application.
diff --git a/samples/PlatformLibrary/client/Android.mk b/samples/PlatformLibrary/client/Android.mk
new file mode 100644
index 0000000..cfd5493
--- /dev/null
+++ b/samples/PlatformLibrary/client/Android.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2008 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.
+#
+
+# This makefile is an example of writing an application that will link against
+# a custom shared library included with an Android system.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# This is the target being built.
+LOCAL_PACKAGE_NAME := PlatformLibraryClient
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Link against the current Android SDK.
+LOCAL_SDK_VERSION := current
+
+# Also link against our own custom library.
+LOCAL_JAVA_LIBRARIES := com.example.android.platform_library
+
+include $(BUILD_PACKAGE)
diff --git a/samples/PlatformLibrary/client/AndroidManifest.xml b/samples/PlatformLibrary/client/AndroidManifest.xml
new file mode 100644
index 0000000..be0d9a1
--- /dev/null
+++ b/samples/PlatformLibrary/client/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This is an example of writing a client application for a custom
+     platform library. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.platform_library.client">
+    
+    <application android:label="Platform Lib Client">
+    
+        <!-- This tells the system about the custom library used by the
+             application, so that it can be properly loaded and linked
+             to the app when the app is initialized. -->
+        <uses-library android:name="com.example.android.platform_library" />
+        
+        <activity android:name="Client">
+            <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/PlatformLibrary/client/src/com/example/android/platform_library/client/Client.java b/samples/PlatformLibrary/client/src/com/example/android/platform_library/client/Client.java
new file mode 100644
index 0000000..8722c72
--- /dev/null
+++ b/samples/PlatformLibrary/client/src/com/example/android/platform_library/client/Client.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.platform_library.client;
+
+import com.example.android.platform_library.PlatformLibrary;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Use a custom platform library.
+ */
+public class Client extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Call an API on the library.
+        PlatformLibrary pl = new PlatformLibrary();
+        int res = pl.getInt(false);
+        
+        // We'll just make our own view to show the result.
+        TextView tv = new TextView(this);
+        tv.setText("Got from lib: " + res);
+        setContentView(tv);
+    }
+}
+
diff --git a/samples/PlatformLibrary/com.example.android.platform_library.xml b/samples/PlatformLibrary/com.example.android.platform_library.xml
new file mode 100644
index 0000000..b9491d8
--- /dev/null
+++ b/samples/PlatformLibrary/com.example.android.platform_library.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+    <library name="com.example.android.platform_library"
+            file="/system/framework/com.example.android.platform_library.jar"/>
+</permissions>
diff --git a/samples/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java b/samples/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
new file mode 100644
index 0000000..68154ec
--- /dev/null
+++ b/samples/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 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.platform_library;
+
+import android.util.Config;
+import android.util.Log;
+
+public final class PlatformLibrary {    
+    static {
+        /*
+         * Load the library.  If it's already loaded, this does nothing.
+         */
+        System.loadLibrary("platform_library_jni");
+    }
+
+    private int mJniInt = -1;
+
+    public PlatformLibrary() {}
+
+    /*
+     * Test native methods.
+     */
+    public int getInt(boolean bad) {
+        /* this alters mJniInt */
+        int result = getJniInt(bad);
+
+        /* reverse a string, for no very good reason */
+        String reverse = reverseString("Android!");
+
+        Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'");
+
+        return mJniInt;
+    }
+
+    /*
+     * Simple method, called from native code.
+     */
+    private static void yodel(String msg) {
+        Log.d("PlatformLibrary", "yodel: " + msg);
+    }
+
+    /*
+     * Trivial native method call.  If "bad" is true, this will throw an
+     * exception.
+     */
+    native private int getJniInt(boolean bad);
+
+    /*
+     * Native method that returns a new string that is the reverse of
+     * the original.  This also calls yodel().
+     */
+    native private static String reverseString(String str);
+}
diff --git a/samples/PlatformLibrary/jni/Android.mk b/samples/PlatformLibrary/jni/Android.mk
new file mode 100644
index 0000000..1bdefa1
--- /dev/null
+++ b/samples/PlatformLibrary/jni/Android.mk
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2008 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.
+#
+
+# This makefile supplies the rules for building a library of JNI code for
+# use by our example platform shared library.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# This is the target being built.
+LOCAL_MODULE:= libplatform_library_jni
+
+# All of the source files that we will compile.
+LOCAL_SRC_FILES:= \
+	PlatformLibrary.cpp
+
+# All of the shared libraries we link against.
+LOCAL_SHARED_LIBRARIES := \
+	libandroid_runtime \
+	libnativehelper \
+	libcutils \
+	libutils
+
+# No static libraries.
+LOCAL_STATIC_LIBRARIES :=
+
+# Also need the JNI headers.
+LOCAL_C_INCLUDES += \
+	$(JNI_H_INCLUDE)
+
+# No specia compiler flags.
+LOCAL_CFLAGS +=
+
+# Don't prelink this library.  For more efficient code, you may want
+# to add this library to the prelink map and set this to true.
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/samples/PlatformLibrary/jni/PlatformLibrary.cpp b/samples/PlatformLibrary/jni/PlatformLibrary.cpp
new file mode 100644
index 0000000..ad60002
--- /dev/null
+++ b/samples/PlatformLibrary/jni/PlatformLibrary.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define LOG_TAG "PlatformLibrary"
+#include "utils/Log.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "jni.h"
+
+
+// ----------------------------------------------------------------------------
+
+/*
+ * Field/method IDs and class object references.
+ *
+ * You should not need to store the JNIEnv pointer in here.  It is
+ * thread-specific and will be passed back in on every call.
+ */
+static struct {
+    jclass      platformLibraryClass;
+    jfieldID    jniInt;
+    jmethodID   yodel;
+} gCachedState;
+
+// ----------------------------------------------------------------------------
+
+/*
+ * Helper function to throw an arbitrary exception.
+ *
+ * Takes the exception class name, a format string, and one optional integer
+ * argument (useful for including an error code, perhaps from errno).
+ */
+static void throwException(JNIEnv* env, const char* ex, const char* fmt,
+    int data) {
+
+    if (jclass cls = env->FindClass(ex)) {
+        if (fmt != NULL) {
+            char msg[1000];
+            snprintf(msg, sizeof(msg), fmt, data);
+            env->ThrowNew(cls, msg);
+        } else {
+            env->ThrowNew(cls, NULL);
+        }
+
+        /*
+         * This is usually not necessary -- local references are released
+         * automatically when the native code returns to the VM.  It's
+         * required if the code doesn't actually return, e.g. it's sitting
+         * in a native event loop.
+         */
+        env->DeleteLocalRef(cls);
+    }
+}
+
+/*
+ * Trivial sample method.
+ *
+ * If "bad" is true, this throws an exception.  Otherwise, this sets the
+ * "mJniInt" field to 42 and returns 24.
+ */
+static jint PlatformLibrary_getJniInt(JNIEnv* env, jobject thiz, jboolean bad) {
+    if (bad) {
+        throwException(env, "java/lang/IllegalStateException",
+                "you are bad", 0);
+        return 0;       /* return value will be ignored */
+    }
+    env->SetIntField(thiz, gCachedState.jniInt, 42);
+    return (jint)24;
+}
+
+/*
+ * A more complex sample method.
+ *
+ * This takes a String as an argument, and returns a new String with
+ * characters in reverse order.  The new string is passed to another method.
+ * This demonstrates basic String manipulation functions and method
+ * invocation.
+ *
+ * This method is declared "static", so there's no "this" pointer; instead,
+ * we get a pointer to the class object.
+ */
+static jstring PlatformLibrary_reverseString(JNIEnv* env, jclass clazz,
+    jstring str) {
+
+    if (str == NULL) {
+        throwException(env, "java/lang/NullPointerException", NULL, 0);
+        return NULL;
+    }
+
+    /*
+     * Get a pointer to the string's UTF-16 character data.  The data
+     * may be a copy or a pointer to the original.  Since String data
+     * is immutable, we're not allowed to touch it.
+     */
+    const jchar* strChars = env->GetStringChars(str, NULL);
+    if (strChars == NULL) {
+        /* something went wrong */
+        LOGW("Couldn't get string chars\n");
+        return NULL;
+    }
+    jsize strLength = env->GetStringLength(str);
+
+    /*
+     * Write a progress message to the log.  Log messages are UTF-8, so
+     * we want to convert the string to show it.
+     */
+    const char* printable = env->GetStringUTFChars(str, NULL);
+    if (printable != NULL) {
+        LOGD("Reversing string '%s'\n", printable);
+        env->ReleaseStringUTFChars(str, printable);
+    }
+
+    /*
+     * Copy the characters to temporary storage, reversing as we go.
+     */
+    jchar tempChars[strLength];
+    for (int i = 0; i < strLength; i++) {
+        tempChars[i] = strChars[strLength -1 -i];
+    }
+
+    /*
+     * Release the original String.  That way, if something fails later on,
+     * we don't have to worry about this leading to a memory leak.
+     */
+    env->ReleaseStringChars(str, strChars);
+    strChars = NULL;            /* this pointer no longer valid */
+
+    /*
+     * Create a new String with the chars.
+     */
+    jstring result = env->NewString(tempChars, strLength);
+    if (result == NULL) {
+        LOGE("NewString failed\n");
+        return NULL;
+    }
+
+    /*
+     * Now let's do something with it.  We already have the methodID for
+     * "yodel", so we can invoke it directly.  It's in our class, so we
+     * can use the Class object reference that was passed in.
+     */
+    env->CallStaticVoidMethod(clazz, gCachedState.yodel, result);
+
+    return result;
+}
+
+
+// ----------------------------------------------------------------------------
+
+/*
+ * Array of methods.
+ *
+ * Each entry has three fields: the name of the method, the method
+ * signature, and a pointer to the native implementation.
+ */
+static const JNINativeMethod gMethods[] = {
+    { "getJniInt",          "(Z)I",
+                        (void*)PlatformLibrary_getJniInt },
+    { "reverseString",      "(Ljava/lang/String;)Ljava/lang/String;",
+                        (void*)PlatformLibrary_reverseString },
+};
+
+/*
+ * Do some (slow-ish) lookups now and save the results.
+ *
+ * Returns 0 on success.
+ */
+static int cacheIds(JNIEnv* env, jclass clazz) {
+    /*
+     * Save the class in case we want to use it later.  Because this is a
+     * reference to the Class object, we need to convert it to a JNI global
+     * reference.
+     */
+    gCachedState.platformLibraryClass = (jclass) env->NewGlobalRef(clazz);
+    if (clazz == NULL) {
+        LOGE("Can't create new global ref\n");
+        return -1;
+    }
+
+    /*
+     * Cache field and method IDs.  IDs are not references, which means we
+     * don't need to call NewGlobalRef on them.
+     */
+    gCachedState.jniInt = env->GetFieldID(clazz, "mJniInt", "I");
+    if (gCachedState.jniInt == NULL) {
+        LOGE("Can't find PlatformLibrary.mJniInt\n");
+        return -1;
+    }
+
+    gCachedState.yodel = env->GetStaticMethodID(clazz, "yodel",
+        "(Ljava/lang/String;)V");
+    if (gCachedState.yodel == NULL) {
+        LOGE("Can't find PlatformLibrary.yodel\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * Explicitly register all methods for our class.
+ *
+ * While we're at it, cache some class references and method/field IDs.
+ *
+ * Returns 0 on success.
+ */
+static int registerMethods(JNIEnv* env) {
+    static const char* const kClassName =
+        "com/example/android/platform_library/PlatformLibrary";
+    jclass clazz;
+
+    /* look up the class */
+    clazz = env->FindClass(kClassName);
+    if (clazz == NULL) {
+        LOGE("Can't find class %s\n", kClassName);
+        return -1;
+    }
+
+    /* register all the methods */
+    if (env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
+    {
+        LOGE("Failed registering methods for %s\n", kClassName);
+        return -1;
+    }
+
+    /* fill out the rest of the ID cache */
+    return cacheIds(env, clazz);
+}
+
+// ----------------------------------------------------------------------------
+
+/*
+ * This is called by the VM when the shared library is first loaded.
+ */
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv* env = NULL;
+    jint result = -1;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        LOGE("ERROR: GetEnv failed\n");
+        goto bail;
+    }
+    assert(env != NULL);
+
+    if (registerMethods(env) != 0) {
+        LOGE("ERROR: PlatformLibrary native registration failed\n");
+        goto bail;
+    }
+
+    /* success -- return valid version number */
+    result = JNI_VERSION_1_4;
+
+bail:
+    return result;
+}
diff --git a/samples/RSSReader/Android.mk b/samples/RSSReader/Android.mk
new file mode 100644
index 0000000..6f95cb4
--- /dev/null
+++ b/samples/RSSReader/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_PACKAGE_NAME := RSSReader
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/samples/RSSReader/AndroidManifest.xml b/samples/RSSReader/AndroidManifest.xml
new file mode 100644
index 0000000..c59411d
--- /dev/null
+++ b/samples/RSSReader/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.rssreader">
+  <uses-permission android:name="android.permission.INTERNET" />
+  <application android:label="RSS Reader">
+        <activity android:name="RssReader">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+		</activity>
+
+  </application>
+</manifest>
diff --git a/samples/RSSReader/res/layout/rss_layout.xml b/samples/RSSReader/res/layout/rss_layout.xml
new file mode 100644
index 0000000..842f4f7
--- /dev/null
+++ b/samples/RSSReader/res/layout/rss_layout.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:layout_width="fill_parent" 
+    android:layout_height="fill_parent"
+    android:padding="10dip"
+    android:orientation="vertical">
+
+	<EditText android:id="@+id/urltext"
+	    android:layout_width="fill_parent"
+	    android:layout_height="wrap_content"
+	    android:textSize="12sp"
+	    android:autoText="false"
+	    android:capitalize="none"
+	    android:text="@string/rss_layout_urltext_text" />
+	
+	<Button android:id="@+id/download"
+	    android:layout_width="wrap_content"
+	    android:layout_height="wrap_content"
+		android:text="@string/rss_layout_download_text" />
+	
+	<TextView android:id="@+id/statustext"
+	    android:layout_width="fill_parent"
+	    android:layout_height="wrap_content"
+	    android:autoText="false"
+	    android:capitalize="none"
+	    android:textSize="12sp"
+	    android:text="@string/rss_layout_statustext_text" />
+	
+	<ListView android:id="@android:id/list"
+	    android:layout_width="fill_parent"
+	    android:layout_height="0dip"
+	    android:layout_weight="1"
+	    android:drawSelectorOnTop="false"/>
+    
+</LinearLayout>
diff --git a/samples/RSSReader/res/values/strings.xml b/samples/RSSReader/res/values/strings.xml
new file mode 100644
index 0000000..83b7efe
--- /dev/null
+++ b/samples/RSSReader/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?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>
+
+    <string name="rss_layout_urltext_text">http://rss.slashdot.org/Slashdot/slashdot</string>
+    <string name="rss_layout_statustext_text"></string>
+    <string name="rss_layout_download_text">Download</string>
+
+</resources>
diff --git a/samples/RSSReader/src/com/example/android/rssreader/RssItem.java b/samples/RSSReader/src/com/example/android/rssreader/RssItem.java
new file mode 100644
index 0000000..e1e798a
--- /dev/null
+++ b/samples/RSSReader/src/com/example/android/rssreader/RssItem.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.rssreader;
+
+/**
+ * Simple struct class to hold the data for one rss item --
+ * title, link, description.
+ */
+public class RssItem  {
+    private CharSequence mTitle;
+    private CharSequence mLink;
+    private CharSequence mDescription;
+    
+    public RssItem() {
+        mTitle = "";
+        mLink = "";
+        mDescription = "";
+    }
+    
+    public RssItem(CharSequence title, CharSequence link, CharSequence description) {
+        mTitle = title;
+        mLink = link;
+        mDescription = description;
+    }
+
+    public CharSequence getDescription() {
+        return mDescription;
+    }
+
+    public void setDescription(CharSequence description) {
+        mDescription = description;
+    }
+
+    public CharSequence getLink() {
+        return mLink;
+    }
+
+    public void setLink(CharSequence link) {
+        mLink = link;
+    }
+
+    public CharSequence getTitle() {
+        return mTitle;
+    }
+
+    public void setTitle(CharSequence title) {
+        mTitle = title;
+    }
+     
+// If we made this class Parcelable, the code would look like...
+
+//    public void writeToParcel(Parcel parcel) {
+//        parcel.writeString(mTitle.toString());
+//        parcel.writeString(mLink.toString());
+//        parcel.writeString(mDescription.toString());
+//    }
+//    
+//    
+//    public static Object createFromParcel(Parcel parcel) {
+//        return new RssItem(
+//                parcel.readString(),
+//                parcel.readString(),
+//                parcel.readString());
+//    }
+}
+
diff --git a/samples/RSSReader/src/com/example/android/rssreader/RssReader.java b/samples/RSSReader/src/com/example/android/rssreader/RssReader.java
new file mode 100644
index 0000000..2f273c4
--- /dev/null
+++ b/samples/RSSReader/src/com/example/android/rssreader/RssReader.java
@@ -0,0 +1,599 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.rssreader;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.TwoLineListItem;
+import android.util.Xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The RssReader example demonstrates forking off a thread to download
+ * rss data in the background and post the results to a ListView in the UI.
+ * It also shows how to display custom data in a ListView
+ * with a ArrayAdapter subclass.
+ * 
+ * <ul>
+ * <li>We own a ListView
+ * <li>The ListView uses our custom RSSListAdapter which 
+ * <ul>
+ * <li>The adapter feeds data to the ListView
+ * <li>Override of getView() in the adapter provides the display view
+ * used for selected list items
+ * </ul>
+ * <li>Override of onListItemClick() creates an intent to open the url for that
+ * RssItem in the browser.
+ * <li>Download = fork off a worker thread
+ * <li>The worker thread opens a network connection for the rss data
+ * <li>Uses XmlPullParser to extract the rss item data
+ * <li>Uses mHandler.post() to send new RssItems to the UI
+ * <li>Supports onSaveInstanceState()/onRestoreInstanceState() to save list/selection state on app
+ * pause, so can resume seamlessly
+ * </ul>
+ */
+public class RssReader extends ListActivity {
+    /**
+     * Custom list adapter that fits our rss data into the list.
+     */
+    private RSSListAdapter mAdapter;
+    
+    /**
+     * Url edit text field.
+     */
+    private EditText mUrlText;
+
+    /**
+     * Status text field.
+     */
+    private TextView mStatusText;
+
+    /**
+     * Handler used to post runnables to the UI thread.
+     */
+    private Handler mHandler;
+
+    /**
+     * Currently running background network thread.
+     */
+    private RSSWorker mWorker;
+
+    // Take this many chars from the front of the description.
+    public static final int SNIPPET_LENGTH = 90;
+    
+    
+    // Keys used for data in the onSaveInstanceState() Map.
+    public static final String STRINGS_KEY = "strings";
+
+    public static final String SELECTION_KEY = "selection";
+
+    public static final String URL_KEY = "url";
+    
+    public static final String STATUS_KEY = "status";
+
+    /**
+     * Called when the activity starts up. Do activity initialization
+     * here, not in a constructor.
+     * 
+     * @see Activity#onCreate
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.rss_layout);
+        // The above layout contains a list id "android:list"
+        // which ListActivity adopts as its list -- we can
+        // access it with getListView().
+
+        // Install our custom RSSListAdapter.
+        List<RssItem> items = new ArrayList<RssItem>();
+        mAdapter = new RSSListAdapter(this, items);
+        getListView().setAdapter(mAdapter);
+
+        // Get pointers to the UI elements in the rss_layout
+        mUrlText = (EditText)findViewById(R.id.urltext);
+        mStatusText = (TextView)findViewById(R.id.statustext);
+        
+        Button download = (Button)findViewById(R.id.download);
+        download.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                doRSS(mUrlText.getText());
+            }
+        });
+
+        // Need one of these to post things back to the UI thread.
+        mHandler = new Handler();
+        
+        // NOTE: this could use the icicle as done in
+        // onRestoreInstanceState().
+    }
+
+    /**
+     * ArrayAdapter encapsulates a java.util.List of T, for presentation in a
+     * ListView. This subclass specializes it to hold RssItems and display
+     * their title/description data in a TwoLineListItem.
+     */
+    private class RSSListAdapter extends ArrayAdapter<RssItem> {
+        private LayoutInflater mInflater;
+
+        public RSSListAdapter(Context context, List<RssItem> objects) {
+            super(context, 0, objects);
+
+            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        /**
+         * This is called to render a particular item for the on screen list.
+         * Uses an off-the-shelf TwoLineListItem view, which contains text1 and
+         * text2 TextViews. We pull data from the RssItem and set it into the
+         * view. The convertView is the view from a previous getView(), so
+         * we can re-use it.
+         * 
+         * @see ArrayAdapter#getView
+         */
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            TwoLineListItem view;
+
+            // Here view may be passed in for re-use, or we make a new one.
+            if (convertView == null) {
+                view = (TwoLineListItem) mInflater.inflate(android.R.layout.simple_list_item_2,
+                        null);
+            } else {
+                view = (TwoLineListItem) convertView;
+            }
+
+            RssItem item = this.getItem(position);
+
+            // Set the item title and description into the view.
+            // This example does not render real HTML, so as a hack to make
+            // the description look better, we strip out the
+            // tags and take just the first SNIPPET_LENGTH chars.
+            view.getText1().setText(item.getTitle());
+            String descr = item.getDescription().toString();
+            descr = removeTags(descr);
+            view.getText2().setText(descr.substring(0, Math.min(descr.length(), SNIPPET_LENGTH)));
+            return view;
+        }
+
+    }
+
+    /**
+     * Simple code to strip out <tag>s -- primitive way to sortof display HTML as
+     * plain text.
+     */
+    public String removeTags(String str) {
+        str = str.replaceAll("<.*?>", " ");
+        str = str.replaceAll("\\s+", " ");
+        return str;
+    }
+
+    /**
+     * Called when user clicks an item in the list. Starts an activity to
+     * open the url for that item.
+     */
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        RssItem item = mAdapter.getItem(position);
+
+        // Creates and starts an intent to open the item.link url.
+        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.getLink().toString()));
+        startActivity(intent);
+    }
+
+    /**
+     * Resets the output UI -- list and status text empty.
+     */
+    public void resetUI() {
+        // Reset the list to be empty.
+        List<RssItem> items = new ArrayList<RssItem>();
+        mAdapter = new RSSListAdapter(this, items);
+        getListView().setAdapter(mAdapter);
+
+        mStatusText.setText("");
+        mUrlText.requestFocus();
+    }
+
+    /**
+     * Sets the currently active running worker. Interrupts any earlier worker,
+     * so we only have one at a time.
+     * 
+     * @param worker the new worker
+     */
+    public synchronized void setCurrentWorker(RSSWorker worker) {
+        if (mWorker != null) mWorker.interrupt();
+        mWorker = worker;
+    }
+
+    /**
+     * Is the given worker the currently active one.
+     * 
+     * @param worker
+     * @return
+     */
+    public synchronized boolean isCurrentWorker(RSSWorker worker) {
+        return (mWorker == worker);
+    }
+
+    /**
+     * Given an rss url string, starts the rss-download-thread going.
+     * 
+     * @param rssUrl
+     */
+    private void doRSS(CharSequence rssUrl) {
+        RSSWorker worker = new RSSWorker(rssUrl);
+        setCurrentWorker(worker);
+
+        resetUI();
+        mStatusText.setText("Downloading\u2026");
+
+        worker.start();
+    }
+
+    /**
+     * Runnable that the worker thread uses to post RssItems to the
+     * UI via mHandler.post
+     */
+    private class ItemAdder implements Runnable {
+        RssItem mItem;
+
+        ItemAdder(RssItem item) {
+            mItem = item;
+        }
+
+        public void run() {
+            mAdapter.add(mItem);
+        }
+
+        // NOTE: Performance idea -- would be more efficient to have he option
+        // to add multiple items at once, so you get less "update storm" in the UI
+        // compared to adding things one at a time.
+    }
+
+    /**
+     * Worker thread takes in an rss url string, downloads its data, parses
+     * out the rss items, and communicates them back to the UI as they are read.
+     */
+    private class RSSWorker extends Thread {
+        private CharSequence mUrl;
+
+        public RSSWorker(CharSequence url) {
+            mUrl = url;
+        }
+
+        @Override
+        public void run() {
+            String status = "";
+            try {
+                // Standard code to make an HTTP connection.
+                URL url = new URL(mUrl.toString());
+                URLConnection connection = url.openConnection();
+                connection.setConnectTimeout(10000);
+
+                connection.connect();
+                InputStream in = connection.getInputStream();
+
+                parseRSS(in, mAdapter);
+                status = "done";
+            } catch (Exception e) {
+                status = "failed:" + e.getMessage();
+            }
+
+            // Send status to UI (unless a newer worker has started)
+            // To communicate back to the UI from a worker thread,
+            // pass a Runnable to handler.post().
+            final String temp = status;
+            if (isCurrentWorker(this)) {
+                mHandler.post(new Runnable() {
+                    public void run() {
+                        mStatusText.setText(temp);
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Populates the menu.
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        menu.add(0, 0, 0, "Slashdot")
+            .setOnMenuItemClickListener(new RSSMenu("http://rss.slashdot.org/Slashdot/slashdot"));
+
+        menu.add(0, 0, 0, "Google News")
+            .setOnMenuItemClickListener(new RSSMenu("http://news.google.com/?output=rss"));
+        
+        menu.add(0, 0, 0, "News.com")
+            .setOnMenuItemClickListener(new RSSMenu("http://news.com.com/2547-1_3-0-20.xml"));
+
+        menu.add(0, 0, 0, "Bad Url")
+            .setOnMenuItemClickListener(new RSSMenu("http://nifty.stanford.edu:8080"));
+
+        menu.add(0, 0, 0, "Reset")
+                .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+            public boolean onMenuItemClick(MenuItem item) {
+                resetUI();
+                return true;
+            }
+        });
+
+        return true;
+    }
+
+    /**
+     * Puts text in the url text field and gives it focus. Used to make a Runnable
+     * for each menu item. This way, one inner class works for all items vs. an
+     * anonymous inner class for each menu item.
+     */
+    private class RSSMenu implements MenuItem.OnMenuItemClickListener {
+        private CharSequence mUrl;
+
+        RSSMenu(CharSequence url) {
+            mUrl = url;
+        }
+
+        public boolean onMenuItemClick(MenuItem item) {
+            mUrlText.setText(mUrl);
+            mUrlText.requestFocus();
+            return true;
+        }
+    }
+
+
+    /**
+     * Called for us to save out our current state before we are paused,
+     * such a for example if the user switches to another app and memory
+     * gets scarce. The given outState is a Bundle to which we can save
+     * objects, such as Strings, Integers or lists of Strings. In this case, we
+     * save out the list of currently downloaded rss data, (so we don't have to
+     * re-do all the networking just because the user goes back and forth
+     * between aps) which item is currently selected, and the data for the text views.
+     * In onRestoreInstanceState() we look at the map to reconstruct the run-state of the
+     * application, so returning to the activity looks seamlessly correct.
+     * TODO: the Activity javadoc should give more detail about what sort of
+     * data can go in the outState map.
+     * 
+     * @see android.app.Activity#onSaveInstanceState
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        // Make a List of all the RssItem data for saving
+        // NOTE: there may be a way to save the RSSItems directly,
+        // rather than their string data.
+        int count = mAdapter.getCount();
+
+        // Save out the items as a flat list of CharSequence objects --
+        // title0, link0, descr0, title1, link1, ...
+        ArrayList<CharSequence> strings = new ArrayList<CharSequence>();
+        for (int i = 0; i < count; i++) {
+            RssItem item = mAdapter.getItem(i);
+            strings.add(item.getTitle());
+            strings.add(item.getLink());
+            strings.add(item.getDescription());
+        }
+        outState.putSerializable(STRINGS_KEY, strings);
+
+        // Save current selection index (if focussed)
+        if (getListView().hasFocus()) {
+            outState.putInt(SELECTION_KEY, Integer.valueOf(getListView().getSelectedItemPosition()));
+        }
+
+        // Save url
+        outState.putString(URL_KEY, mUrlText.getText().toString());
+        
+        // Save status
+        outState.putCharSequence(STATUS_KEY, mStatusText.getText());
+    }
+
+    /**
+     * Called to "thaw" re-animate the app from a previous onSaveInstanceState().
+     * 
+     * @see android.app.Activity#onRestoreInstanceState
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+
+        // Note: null is a legal value for onRestoreInstanceState.
+        if (state == null) return;
+
+        // Restore items from the big list of CharSequence objects
+        List<CharSequence> strings = (ArrayList<CharSequence>)state.getSerializable(STRINGS_KEY);
+        List<RssItem> items = new ArrayList<RssItem>();
+        for (int i = 0; i < strings.size(); i += 3) {
+            items.add(new RssItem(strings.get(i), strings.get(i + 1), strings.get(i + 2)));
+        }
+
+        // Reset the list view to show this data.
+        mAdapter = new RSSListAdapter(this, items);
+        getListView().setAdapter(mAdapter);
+
+        // Restore selection
+        if (state.containsKey(SELECTION_KEY)) {
+            getListView().requestFocus(View.FOCUS_FORWARD);
+            // todo: is above right? needed it to work
+            getListView().setSelection(state.getInt(SELECTION_KEY));
+        }
+        
+        // Restore url
+        mUrlText.setText(state.getCharSequence(URL_KEY));
+        
+        // Restore status
+        mStatusText.setText(state.getCharSequence(STATUS_KEY));
+    }
+
+    
+    
+    /**
+     * Does rudimentary RSS parsing on the given stream and posts rss items to
+     * the UI as they are found. Uses Android's XmlPullParser facility. This is
+     * not a production quality RSS parser -- it just does a basic job of it.
+     * 
+     * @param in stream to read
+     * @param adapter adapter for ui events
+     */
+    void parseRSS(InputStream in, RSSListAdapter adapter) throws IOException,
+            XmlPullParserException {
+        // TODO: switch to sax
+
+        XmlPullParser xpp = Xml.newPullParser();
+        xpp.setInput(in, null);  // null = parser figures out encoding
+
+        int eventType;
+        String title = "";
+        String link = "";
+        String description = "";
+        eventType = xpp.getEventType();
+        while (eventType != XmlPullParser.END_DOCUMENT) {
+            if (eventType == XmlPullParser.START_TAG) {
+                String tag = xpp.getName();
+                if (tag.equals("item")) {
+                    title = link = description = "";
+                } else if (tag.equals("title")) {
+                    xpp.next(); // Skip to next element -- assume text is directly inside the tag
+                    title = xpp.getText();
+                } else if (tag.equals("link")) {
+                    xpp.next();
+                    link = xpp.getText();
+                } else if (tag.equals("description")) {
+                    xpp.next();
+                    description = xpp.getText();
+                }
+            } else if (eventType == XmlPullParser.END_TAG) {
+                // We have a comlete item -- post it back to the UI
+                // using the mHandler (necessary because we are not
+                // running on the UI thread).
+                String tag = xpp.getName();
+                if (tag.equals("item")) {
+                    RssItem item = new RssItem(title, link, description);
+                    mHandler.post(new ItemAdder(item));
+                }
+            }
+            eventType = xpp.next();
+        }
+    }
+    
+    // SAX version of the code to do the parsing.
+    /*
+    private class RSSHandler extends DefaultHandler {
+        RSSListAdapter mAdapter;
+        
+        String mTitle;
+        String mLink;
+        String mDescription;
+        
+        StringBuilder mBuff;
+        
+        boolean mInItem;
+        
+        public RSSHandler(RSSListAdapter adapter) {
+            mAdapter = adapter;
+            mInItem = false;
+            mBuff = new StringBuilder();
+        }
+        
+        public void startElement(String uri,
+                String localName,
+                String qName,
+                Attributes atts)
+                throws SAXException {
+            String tag = localName;
+            if (tag.equals("")) tag = qName;
+            
+            // If inside <item>, clear out buff on each tag start
+            if (mInItem) {
+                mBuff.delete(0, mBuff.length());
+            }
+            
+            if (tag.equals("item")) {
+                mTitle = mLink = mDescription = "";
+                mInItem = true;
+            }
+        }
+        
+        public void characters(char[] ch,
+                      int start,
+                      int length)
+                      throws SAXException {
+            // Buffer up all the chars when inside <item>
+            if (mInItem) mBuff.append(ch, start, length);
+        }
+                      
+        public void endElement(String uri,
+                      String localName,
+                      String qName)
+                      throws SAXException {
+            String tag = localName;
+            if (tag.equals("")) tag = qName;
+            
+            // For each tag, copy buff chars to right variable
+            if (tag.equals("title")) mTitle = mBuff.toString();
+            else if (tag.equals("link")) mLink = mBuff.toString();
+            if (tag.equals("description")) mDescription = mBuff.toString();
+            
+            // Have all the data at this point .... post it to the UI.
+            if (tag.equals("item")) {
+                RssItem item = new RssItem(mTitle, mLink, mDescription);
+                mHandler.post(new ItemAdder(item));
+                mInItem = false;
+            }
+        }
+    }
+    */
+    
+    /*
+    public void parseRSS2(InputStream in, RSSListAdapter adapter) throws IOException {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            DefaultHandler handler = new RSSHandler(adapter);
+            
+            parser.parse(in, handler);
+            // TODO: does the parser figure out the encoding right on its own?
+    }
+    */
+}
diff --git a/samples/SimpleJNI/Android.mk b/samples/SimpleJNI/Android.mk
new file mode 100644
index 0000000..a45ada8
--- /dev/null
+++ b/samples/SimpleJNI/Android.mk
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2008 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.
+#
+
+# This makefile shows how to build a shared library and an activity that
+# bundles the shared library and calls it using JNI.
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(TOP_LOCAL_PATH)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := SimpleJNI
+
+LOCAL_JNI_SHARED_LIBRARIES := libsimplejni
+
+include $(BUILD_PACKAGE)
+
+# ============================================================
+
+# Also build all of the sub-targets under this one: the shared library.
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/samples/SimpleJNI/AndroidManifest.xml b/samples/SimpleJNI/AndroidManifest.xml
new file mode 100644
index 0000000..b163d55
--- /dev/null
+++ b/samples/SimpleJNI/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- This is an example of writing an application that bundles a
+     native code library. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.example.android.simplejni">
+    <application android:label="Simple JNI">
+        <activity android:name="SimpleJNI">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest> 
\ No newline at end of file
diff --git a/samples/SimpleJNI/jni/Android.mk b/samples/SimpleJNI/jni/Android.mk
new file mode 100644
index 0000000..528196b
--- /dev/null
+++ b/samples/SimpleJNI/jni/Android.mk
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2008 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.
+#
+
+# This makefile supplies the rules for building a library of JNI code for
+# use by our example of how to bundle a shared library with an APK.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# This is the target being built.
+LOCAL_MODULE:= libsimplejni
+
+
+# All of the source files that we will compile.
+LOCAL_SRC_FILES:= \
+  native.cpp
+
+# All of the shared libraries we link against.
+LOCAL_SHARED_LIBRARIES := \
+	libutils
+
+# No static libraries.
+LOCAL_STATIC_LIBRARIES :=
+
+# Also need the JNI headers.
+LOCAL_C_INCLUDES += \
+	$(JNI_H_INCLUDE)
+
+# No special compiler flags.
+LOCAL_CFLAGS +=
+
+# Don't prelink this library.  For more efficient code, you may want
+# to add this library to the prelink map and set this to true. However,
+# it's difficult to do this for applications that are not supplied as
+# part of a system image.
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/samples/SimpleJNI/jni/native.cpp b/samples/SimpleJNI/jni/native.cpp
new file mode 100644
index 0000000..4d2e4e0
--- /dev/null
+++ b/samples/SimpleJNI/jni/native.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define LOG_TAG "simplejni native.cpp"
+#include <utils/Log.h>
+
+#include <stdio.h>
+
+#include "jni.h"
+
+static jint
+add(JNIEnv *env, jobject thiz, jint a, jint b) {
+int result = a + b;
+    LOGI("%d + %d = %d", a, b, result);
+    return result;
+}
+
+static const char *classPathName = "com/example/android/simplejni/Native";
+
+static JNINativeMethod methods[] = {
+  {"add", "(II)I", (void*)add },
+};
+
+/*
+ * Register several native methods for one class.
+ */
+static int registerNativeMethods(JNIEnv* env, const char* className,
+    JNINativeMethod* gMethods, int numMethods)
+{
+    jclass clazz;
+
+    clazz = env->FindClass(className);
+    if (clazz == NULL) {
+        LOGE("Native registration unable to find class '%s'", className);
+        return JNI_FALSE;
+    }
+    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
+        LOGE("RegisterNatives failed for '%s'", className);
+        return JNI_FALSE;
+    }
+
+    return JNI_TRUE;
+}
+
+/*
+ * Register native methods for all classes we know about.
+ *
+ * returns JNI_TRUE on success.
+ */
+static int registerNatives(JNIEnv* env)
+{
+  if (!registerNativeMethods(env, classPathName,
+                 methods, sizeof(methods) / sizeof(methods[0]))) {
+    return JNI_FALSE;
+  }
+
+  return JNI_TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+
+/*
+ * This is called by the VM when the shared library is first loaded.
+ */
+ 
+typedef union {
+    JNIEnv* env;
+    void* venv;
+} UnionJNIEnvToVoid;
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    UnionJNIEnvToVoid uenv;
+    uenv.venv = NULL;
+    jint result = -1;
+    JNIEnv* env = NULL;
+    
+    LOGI("JNI_OnLoad");
+
+    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
+        LOGE("ERROR: GetEnv failed");
+        goto bail;
+    }
+    env = uenv.env;
+
+    if (registerNatives(env) != JNI_TRUE) {
+        LOGE("ERROR: registerNatives failed");
+        goto bail;
+    }
+    
+    result = JNI_VERSION_1_4;
+    
+bail:
+    return result;
+}
diff --git a/samples/SimpleJNI/src/com/example/android/simplejni/SimpleJNI.java b/samples/SimpleJNI/src/com/example/android/simplejni/SimpleJNI.java
new file mode 100644
index 0000000..e83cd21
--- /dev/null
+++ b/samples/SimpleJNI/src/com/example/android/simplejni/SimpleJNI.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 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.simplejni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class SimpleJNI extends Activity {
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        TextView tv = new TextView(this);
+        int sum = Native.add(2, 3);
+        tv.setText("2 + 3 = " + Integer.toString(sum));
+        setContentView(tv);
+    }
+}
+
+class Native {
+    static {
+    	// The runtime will add "lib" on the front and ".o" on the end of
+    	// the name supplied to loadLibrary.
+        System.loadLibrary("simplejni");
+    }
+
+    static native int add(int a, int b);
+}
diff --git a/samples/SkeletonApp/Android.mk b/samples/SkeletonApp/Android.mk
new file mode 100644
index 0000000..5bada02
--- /dev/null
+++ b/samples/SkeletonApp/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 := SkeletonApp
+
+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/SkeletonApp/AndroidManifest.xml b/samples/SkeletonApp/AndroidManifest.xml
new file mode 100644
index 0000000..b0b4ef2
--- /dev/null
+++ b/samples/SkeletonApp/AndroidManifest.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+
+<!-- This file describes the code in the SkeletonApp package, which is
+     used by the system to determine how to start your application and
+     integrate it with the rest of the system.  -->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.skeletonapp">
+
+    <!-- This package contains an application...  The 'label' is the name
+         to display to the user for the overall application, and provides
+         a default label for all following components.  The syntax here is a
+         reference to one of our string resources.-->
+    <application android:label="@string/skeleton_app">
+
+        <!-- An Activity in the application - this is something the user
+             can launch and interact with.  The "name" attribute is the
+             name of the class within your package that implements this
+             activity. -->
+        <activity android:name="SkeletonActivity">
+
+            <!-- An IntentFilter tells the system when it should use your
+                 activity.  This allows the user to get to your activity
+                 without someone having to explicitly know to launch your
+                 class "com.examplel.android.skeletonapp.SkeletonActivity". -->
+            <intent-filter>
+                <!-- The MAIN action describes a main entry point into an
+                     activity, without any associated data. -->
+                <action android:name="android.intent.action.MAIN" />
+
+                <!-- This places this activity into the main app list. -->
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/samples/SkeletonApp/readme.txt b/samples/SkeletonApp/readme.txt
new file mode 100644
index 0000000..1ebddbd
--- /dev/null
+++ b/samples/SkeletonApp/readme.txt
@@ -0,0 +1,65 @@
+Android Skeleton App
+~~~~~~~~~~~~~~~~~~~~
+
+
+This directory contains the full implementation of a basic application for
+the Android platform, demonstrating the basic facilities that applications
+will use.  You can run the application either directly from the "test"
+list in the app launcher (it is named Skeleton App) or by selecting it from
+the top list in the Sample Code app.
+
+The files contained here:
+
+
+AndroidManifest.xml
+
+This XML file describes to the Android platform what your application can do.
+It is a required file, and is the mechanism you use to show your application
+to the user (in the app launcher's list), handle data types, etc.
+
+
+src/*
+
+Under this directory is the Java source for for your application.
+
+
+src/com/android/skeletonapp/SkeletonActivity.java
+
+This is the implementation of the "activity" feature described in
+AndroidManifest.xml.  The path each class implementation is
+{src/PACKAGE/CLASS.java}, where PACKAGE comes from the name in the <package>
+tag and CLASS comes from the class in the <activity> tag.
+
+
+res/*
+
+Under this directory are the resources for your application.
+
+
+res/layout/skeleton_activity.xml
+
+The res/layout/ directory contains XML files describing user interface
+view hierarchies.  The skeleton_activity.xml file here is used by
+SkeletonActivity.java to construct its UI.  The base name of each file
+(all text before a '.' character) is taken as the resource name;
+it must be lower-case.
+
+
+res/drawable/violet.png
+
+The res/drawable/ directory contains images and other things that can be
+drawn to the screen.  These can be bitmaps (in .png or .jpeg format) or
+special XML files describing more complex drawings.  The violet.png file
+here is used as the image to display in one of the views in
+skeleton_activity.xml.  Like layout files, the base name is used for the
+resulting resource name.
+
+
+res/values/colors.xml
+res/values/strings.xml
+res/values/styles.xml
+
+These XML files describe additional resources included in the application.
+They all use the same syntax; all of these resources could be defined in one
+file, but we generally split them apart as shown here to keep things organized.
+
diff --git a/samples/SkeletonApp/res/drawable/violet.jpg b/samples/SkeletonApp/res/drawable/violet.jpg
new file mode 100644
index 0000000..d892c40
--- /dev/null
+++ b/samples/SkeletonApp/res/drawable/violet.jpg
Binary files differ
diff --git a/samples/SkeletonApp/res/layout/skeleton_activity.xml b/samples/SkeletonApp/res/layout/skeleton_activity.xml
new file mode 100644
index 0000000..b8dcac7
--- /dev/null
+++ b/samples/SkeletonApp/res/layout/skeleton_activity.xml
@@ -0,0 +1,73 @@
+<?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.
+-->
+
+<!-- This file describes the layout of the main SkeletonApp activity
+     user interface.
+ -->
+
+<!-- The top view is a layout manager that places its child views into
+     a row, here set to be vertical (so the first is at the top) -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent" android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <!-- First view is a text editor.  We want it to use all available
+         horizontal space, and stretch to fill whatever vertical space
+         is available to it.  Note the use of the "id" attribute, which
+         allows us to find this object from the Java code. -->
+    <EditText android:id="@+id/editor"
+        android:layout_width="fill_parent" android:layout_height="0dip"
+        android:autoText="true"
+        android:capitalize="sentences"
+        android:layout_weight="1"
+        android:freezesText="true" >
+        <requestFocus />
+    </EditText>
+
+    <!-- Next view is another linear layout manager, now horizontal.  We
+         give it a custom background; see colors.xml for the definition
+         of drawable/semi_black-->
+    <LinearLayout
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical" android:gravity="center_horizontal"
+        android:orientation="horizontal"
+        android:background="@drawable/semi_black">
+
+        <!-- On the left: the "back" button.  See styles.xml for the
+             definition of style/ActionButton, which we use to hold
+             common attributes that are used for both this and the
+             clear button.  See strings.xml for the definition of
+             string/back. -->
+        <Button android:id="@+id/back" style="@style/ActionButton"
+            android:text="@string/back" />
+
+        <!-- In the middle: a custom image, -->
+        <ImageView android:id="@+id/image"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:paddingLeft="4dip" android_paddingRight="4dip"
+            android:src="@drawable/violet" />
+
+        <!-- On the right: another button, this time with its text color
+             changed to red.  Again, see colors.xml for the definition. -->
+        <Button android:id="@+id/clear" style="@style/ActionButton"
+            android:text="@string/clear" android:textColor="@color/red" />
+
+    </LinearLayout>
+
+</LinearLayout>
+
+
diff --git a/samples/SkeletonApp/res/values/colors.xml b/samples/SkeletonApp/res/values/colors.xml
new file mode 100644
index 0000000..1d985bc
--- /dev/null
+++ b/samples/SkeletonApp/res/values/colors.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+
+<!-- This file contains resource definitions for solid colors.  In
+     addition to plain color resources (retrieved via Resources.getColor()
+     and friends), we are also using it to define drawables that are
+     a solid color. -->
+
+<resources>
+    <!-- Retrieved via Resources.getColor() and friends. -->
+    <color name="red">#f00</color>
+
+    <!-- Retrieved via Resources.getDrawable() and friends. -->
+    <drawable name="semi_black">#80000000</drawable>
+</resources>
diff --git a/samples/SkeletonApp/res/values/strings.xml b/samples/SkeletonApp/res/values/strings.xml
new file mode 100644
index 0000000..4dc998d
--- /dev/null
+++ b/samples/SkeletonApp/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="skeleton_app">Skeleton App</string>
+    <string name="back">Back</string>
+    <string name="clear">Clear</string>
+
+    <!-- This is a complex string containing style runs. -->
+    <string name="main_label">Hello <u>th<ignore>e</ignore>re</u>, <i>you</i> <b>Activity</b>!</string>
+</resources>
+
diff --git a/samples/SkeletonApp/res/values/styles.xml b/samples/SkeletonApp/res/values/styles.xml
new file mode 100644
index 0000000..050514f
--- /dev/null
+++ b/samples/SkeletonApp/res/values/styles.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<!-- This file contains resource definitions for style.  A style is
+     a collection of named values that can be applied as a group.  Here,
+     we are using a style to define a common set of XML attributes that
+     will be used in multiple tags. -->
+
+<resources>
+    <style name="ActionButton">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textAppearance">@style/TextAppearance.ActionButton</item>
+    </style>
+
+    <style name="TextAppearance" parent="android:TextAppearance">
+    </style>
+
+    <style name="TextAppearance.ActionButton">
+        <item name="android:textStyle">italic</item>
+    </style>
+
+</resources>
+
diff --git a/samples/SkeletonApp/src/com/example/android/skeletonapp/SkeletonActivity.java b/samples/SkeletonApp/src/com/example/android/skeletonapp/SkeletonActivity.java
new file mode 100644
index 0000000..7abf3ae
--- /dev/null
+++ b/samples/SkeletonApp/src/com/example/android/skeletonapp/SkeletonActivity.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.skeletonapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * This class provides a basic demonstration of how to write an Android
+ * activity. Inside of its window, it places a single view: an EditText that
+ * displays and edits some internal text.
+ */
+public class SkeletonActivity extends Activity {
+    
+    static final private int BACK_ID = Menu.FIRST;
+    static final private int CLEAR_ID = Menu.FIRST + 1;
+
+    private EditText mEditor;
+    
+    public SkeletonActivity() {
+    }
+
+    /** Called with the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Inflate our UI from its XML layout description.
+        setContentView(R.layout.skeleton_activity);
+
+        // Find the text editor view inside the layout, because we
+        // want to do various programmatic things with it.
+        mEditor = (EditText) findViewById(R.id.editor);
+
+        // Hook up button presses to the appropriate event handler.
+        ((Button) findViewById(R.id.back)).setOnClickListener(mBackListener);
+        ((Button) findViewById(R.id.clear)).setOnClickListener(mClearListener);
+        
+        mEditor.setText(getText(R.string.main_label));
+    }
+
+    /**
+     * Called when the activity is about to start interacting with the user.
+     */
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    /**
+     * Called when your activity's options menu needs to be created.
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        // We are going to create two menus. Note that we assign them
+        // unique integer IDs, labels from our string resources, and
+        // given them shortcuts.
+        menu.add(0, BACK_ID, 0, R.string.back).setShortcut('0', 'b');
+        menu.add(0, CLEAR_ID, 0, R.string.clear).setShortcut('1', 'c');
+
+        return true;
+    }
+
+    /**
+     * Called right before your activity's option menu is displayed.
+     */
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+
+        // Before showing the menu, we need to decide whether the clear
+        // item is enabled depending on whether there is text to clear.
+        menu.findItem(CLEAR_ID).setVisible(mEditor.getText().length() > 0);
+
+        return true;
+    }
+
+    /**
+     * Called when a menu item is selected.
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case BACK_ID:
+            finish();
+            return true;
+        case CLEAR_ID:
+            mEditor.setText("");
+            return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    /**
+     * A call-back for when the user presses the back button.
+     */
+    OnClickListener mBackListener = new OnClickListener() {
+        public void onClick(View v) {
+            finish();
+        }
+    };
+
+    /**
+     * A call-back for when the user presses the clear button.
+     */
+    OnClickListener mClearListener = new OnClickListener() {
+        public void onClick(View v) {
+            mEditor.setText("");
+        }
+    };
+}
diff --git a/samples/SkeletonApp/tests/Android.mk b/samples/SkeletonApp/tests/Android.mk
new file mode 100644
index 0000000..7f26bfa
--- /dev/null
+++ b/samples/SkeletonApp/tests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := SkeletonAppTests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_INSTRUMENTATION_FOR := SkeletonApp
+
+include $(BUILD_PACKAGE)
diff --git a/samples/SkeletonApp/tests/AndroidManifest.xml b/samples/SkeletonApp/tests/AndroidManifest.xml
new file mode 100644
index 0000000..fac1f41
--- /dev/null
+++ b/samples/SkeletonApp/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.skeletonapp.tests">
+    
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+  <instrumentation android:name="android.test.InstrumentationTestRunner"
+      android:targetPackage="com.example.android.skeletonapp"
+      android:label="SkeletonApp sample tests">
+  </instrumentation>  
+  
+</manifest>
diff --git a/samples/SkeletonApp/tests/src/com/example/android/skeletonapp/SkeletonAppTest.java b/samples/SkeletonApp/tests/src/com/example/android/skeletonapp/SkeletonAppTest.java
new file mode 100644
index 0000000..3123348
--- /dev/null
+++ b/samples/SkeletonApp/tests/src/com/example/android/skeletonapp/SkeletonAppTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 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.skeletonapp;
+
+import android.test.ActivityInstrumentationTestCase;
+
+import com.example.android.skeletonapp.SkeletonActivity;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class SkeletonAppTest extends ActivityInstrumentationTestCase<SkeletonActivity> {
+
+  public SkeletonAppTest() {
+      super("com.example.android.skeletonapp", SkeletonActivity.class);
+  }
+}
diff --git a/samples/Snake/Android.mk b/samples/Snake/Android.mk
new file mode 100644
index 0000000..56b642e
--- /dev/null
+++ b/samples/Snake/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 := Snake
+
+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/Snake/AndroidManifest.xml b/samples/Snake/AndroidManifest.xml
new file mode 100644
index 0000000..174e8b4
--- /dev/null
+++ b/samples/Snake/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     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.snake">
+    <application android:label="Snake on a Phone">
+      <activity android:name="Snake"
+        android:screenOrientation="portrait"
+        android:configChanges="keyboardHidden|orientation">
+            <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/Snake/MODULE_LICENSE_APACHE2 b/samples/Snake/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/Snake/MODULE_LICENSE_APACHE2
diff --git a/samples/Snake/res/drawable/greenstar.png b/samples/Snake/res/drawable/greenstar.png
new file mode 100644
index 0000000..26be5c8
--- /dev/null
+++ b/samples/Snake/res/drawable/greenstar.png
Binary files differ
diff --git a/samples/Snake/res/drawable/redstar.png b/samples/Snake/res/drawable/redstar.png
new file mode 100644
index 0000000..e9c0947
--- /dev/null
+++ b/samples/Snake/res/drawable/redstar.png
Binary files differ
diff --git a/samples/Snake/res/drawable/yellowstar.png b/samples/Snake/res/drawable/yellowstar.png
new file mode 100644
index 0000000..134b234
--- /dev/null
+++ b/samples/Snake/res/drawable/yellowstar.png
Binary files differ
diff --git a/samples/Snake/res/layout/snake_layout.xml b/samples/Snake/res/layout/snake_layout.xml
new file mode 100644
index 0000000..583c0c4
--- /dev/null
+++ b/samples/Snake/res/layout/snake_layout.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	
+	<com.example.android.snake.SnakeView
+	 android:id="@+id/snake"
+		android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                tileSize="24"
+                />
+	
+	<RelativeLayout
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent" >
+		
+		<TextView
+		 android:id="@+id/text"
+			android:text="@string/snake_layout_text_text"
+			android:visibility="visible"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_centerInParent="true"
+			android:gravity="center_horizontal"
+			android:textColor="#ff8888ff"
+			android:textSize="24sp"/>
+	</RelativeLayout>
+</FrameLayout>
diff --git a/samples/Snake/res/values/attrs.xml b/samples/Snake/res/values/attrs.xml
new file mode 100644
index 0000000..c846864
--- /dev/null
+++ b/samples/Snake/res/values/attrs.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>
+  <declare-styleable name="TileView">
+    <attr name="tileSize" format="integer" />
+  </declare-styleable>
+</resources>
+
diff --git a/samples/Snake/res/values/strings.xml b/samples/Snake/res/values/strings.xml
new file mode 100644
index 0000000..3c4a89d
--- /dev/null
+++ b/samples/Snake/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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>
+  <string name="mode_ready">Snake\nPress Up To Play</string>
+  <string name="mode_pause">Paused\nPress Up To Resume</string>
+  <string name="mode_lose_prefix">Game Over\nScore: </string>
+  <string name="mode_lose_suffix">\nPress Up To Play</string>
+
+    <string name="snake_layout_text_text"></string>
+</resources>
diff --git a/samples/Snake/src/com/example/android/snake/Snake.java b/samples/Snake/src/com/example/android/snake/Snake.java
new file mode 100644
index 0000000..5fdc024
--- /dev/null
+++ b/samples/Snake/src/com/example/android/snake/Snake.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.snake;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Window;
+import android.widget.TextView;
+
+/**
+ * Snake: a simple game that everyone can enjoy.
+ * 
+ * This is an implementation of the classic Game "Snake", in which you control a
+ * serpent roaming around the garden looking for apples. Be careful, though,
+ * because when you catch one, not only will you become longer, but you'll move
+ * faster. Running into yourself or the walls will end the game.
+ * 
+ */
+public class Snake extends Activity {
+
+    private SnakeView mSnakeView;
+    
+    private static String ICICLE_KEY = "snake-view";
+
+    /**
+     * Called when Activity is first created. Turns off the title bar, sets up
+     * the content views, and fires up the SnakeView.
+     * 
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // No Title bar
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        setContentView(R.layout.snake_layout);
+
+        mSnakeView = (SnakeView) findViewById(R.id.snake);
+        mSnakeView.setTextView((TextView) findViewById(R.id.text));
+
+        if (savedInstanceState == null) {
+            // We were just launched -- set up a new game
+            mSnakeView.setMode(SnakeView.READY);
+        } else {
+            // We are being restored
+            Bundle map = savedInstanceState.getBundle(ICICLE_KEY);
+            if (map != null) {
+                mSnakeView.restoreState(map);
+            } else {
+                mSnakeView.setMode(SnakeView.PAUSE);
+            }
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        // Pause the game along with the activity
+        mSnakeView.setMode(SnakeView.PAUSE);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        //Store the game state
+        outState.putBundle(ICICLE_KEY, mSnakeView.saveState());
+    }
+
+}
diff --git a/samples/Snake/src/com/example/android/snake/SnakeView.java b/samples/Snake/src/com/example/android/snake/SnakeView.java
new file mode 100644
index 0000000..8dd0232
--- /dev/null
+++ b/samples/Snake/src/com/example/android/snake/SnakeView.java
@@ -0,0 +1,553 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.snake;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * SnakeView: implementation of a simple game of Snake
+ * 
+ * 
+ */
+public class SnakeView extends TileView {
+
+    private static final String TAG = "SnakeView";
+
+    /**
+     * Current mode of application: READY to run, RUNNING, or you have already
+     * lost. static final ints are used instead of an enum for performance
+     * reasons.
+     */
+    private int mMode = READY;
+    public static final int PAUSE = 0;
+    public static final int READY = 1;
+    public static final int RUNNING = 2;
+    public static final int LOSE = 3;
+
+    /**
+     * Current direction the snake is headed.
+     */
+    private int mDirection = NORTH;
+    private int mNextDirection = NORTH;
+    private static final int NORTH = 1;
+    private static final int SOUTH = 2;
+    private static final int EAST = 3;
+    private static final int WEST = 4;
+
+    /**
+     * Labels for the drawables that will be loaded into the TileView class
+     */
+    private static final int RED_STAR = 1;
+    private static final int YELLOW_STAR = 2;
+    private static final int GREEN_STAR = 3;
+
+    /**
+     * mScore: used to track the number of apples captured mMoveDelay: number of
+     * milliseconds between snake movements. This will decrease as apples are
+     * captured.
+     */
+    private long mScore = 0;
+    private long mMoveDelay = 600;
+    /**
+     * mLastMove: tracks the absolute time when the snake last moved, and is used
+     * to determine if a move should be made based on mMoveDelay.
+     */
+    private long mLastMove;
+    
+    /**
+     * mStatusText: text shows to the user in some run states
+     */
+    private TextView mStatusText;
+
+    /**
+     * mSnakeTrail: a list of Coordinates that make up the snake's body
+     * mAppleList: the secret location of the juicy apples the snake craves.
+     */
+    private ArrayList<Coordinate> mSnakeTrail = new ArrayList<Coordinate>();
+    private ArrayList<Coordinate> mAppleList = new ArrayList<Coordinate>();
+
+    /**
+     * Everyone needs a little randomness in their life
+     */
+    private static final Random RNG = new Random();
+
+    /**
+     * Create a simple handler that we can use to cause animation to happen.  We
+     * set ourselves as a target and we can use the sleep()
+     * function to cause an update/invalidate to occur at a later date.
+     */
+    private RefreshHandler mRedrawHandler = new RefreshHandler();
+
+    class RefreshHandler extends Handler {
+
+        @Override
+        public void handleMessage(Message msg) {
+            SnakeView.this.update();
+            SnakeView.this.invalidate();
+        }
+
+        public void sleep(long delayMillis) {
+        	this.removeMessages(0);
+            sendMessageDelayed(obtainMessage(0), delayMillis);
+        }
+    };
+
+
+    /**
+     * Constructs a SnakeView based on inflation from XML
+     * 
+     * @param context
+     * @param attrs
+     */
+    public SnakeView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initSnakeView();
+   }
+
+    public SnakeView(Context context, AttributeSet attrs, int defStyle) {
+    	super(context, attrs, defStyle);
+    	initSnakeView();
+    }
+
+    private void initSnakeView() {
+        setFocusable(true);
+
+        Resources r = this.getContext().getResources();
+        
+        resetTiles(4);
+        loadTile(RED_STAR, r.getDrawable(R.drawable.redstar));
+        loadTile(YELLOW_STAR, r.getDrawable(R.drawable.yellowstar));
+        loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar));
+    	
+    }
+    
+
+    private void initNewGame() {
+        mSnakeTrail.clear();
+        mAppleList.clear();
+
+        // For now we're just going to load up a short default eastbound snake
+        // that's just turned north
+
+        
+        mSnakeTrail.add(new Coordinate(7, 7));
+        mSnakeTrail.add(new Coordinate(6, 7));
+        mSnakeTrail.add(new Coordinate(5, 7));
+        mSnakeTrail.add(new Coordinate(4, 7));
+        mSnakeTrail.add(new Coordinate(3, 7));
+        mSnakeTrail.add(new Coordinate(2, 7));
+        mNextDirection = NORTH;
+
+        // Two apples to start with
+        addRandomApple();
+        addRandomApple();
+
+        mMoveDelay = 600;
+        mScore = 0;
+    }
+
+
+    /**
+     * Given a ArrayList of coordinates, we need to flatten them into an array of
+     * ints before we can stuff them into a map for flattening and storage.
+     * 
+     * @param cvec : a ArrayList of Coordinate objects
+     * @return : a simple array containing the x/y values of the coordinates
+     * as [x1,y1,x2,y2,x3,y3...]
+     */
+    private int[] coordArrayListToArray(ArrayList<Coordinate> cvec) {
+        int count = cvec.size();
+        int[] rawArray = new int[count * 2];
+        for (int index = 0; index < count; index++) {
+            Coordinate c = cvec.get(index);
+            rawArray[2 * index] = c.x;
+            rawArray[2 * index + 1] = c.y;
+        }
+        return rawArray;
+    }
+
+    /**
+     * Save game state so that the user does not lose anything
+     * if the game process is killed while we are in the 
+     * background.
+     * 
+     * @return a Bundle with this view's state
+     */
+    public Bundle saveState() {
+        Bundle map = new Bundle();
+
+        map.putIntArray("mAppleList", coordArrayListToArray(mAppleList));
+        map.putInt("mDirection", Integer.valueOf(mDirection));
+        map.putInt("mNextDirection", Integer.valueOf(mNextDirection));
+        map.putLong("mMoveDelay", Long.valueOf(mMoveDelay));
+        map.putLong("mScore", Long.valueOf(mScore));
+        map.putIntArray("mSnakeTrail", coordArrayListToArray(mSnakeTrail));
+
+        return map;
+    }
+
+    /**
+     * Given a flattened array of ordinate pairs, we reconstitute them into a
+     * ArrayList of Coordinate objects
+     * 
+     * @param rawArray : [x1,y1,x2,y2,...]
+     * @return a ArrayList of Coordinates
+     */
+    private ArrayList<Coordinate> coordArrayToArrayList(int[] rawArray) {
+        ArrayList<Coordinate> coordArrayList = new ArrayList<Coordinate>();
+
+        int coordCount = rawArray.length;
+        for (int index = 0; index < coordCount; index += 2) {
+            Coordinate c = new Coordinate(rawArray[index], rawArray[index + 1]);
+            coordArrayList.add(c);
+        }
+        return coordArrayList;
+    }
+
+    /**
+     * Restore game state if our process is being relaunched
+     * 
+     * @param icicle a Bundle containing the game state
+     */
+    public void restoreState(Bundle icicle) {
+        setMode(PAUSE);
+
+        mAppleList = coordArrayToArrayList(icicle.getIntArray("mAppleList"));
+        mDirection = icicle.getInt("mDirection");
+        mNextDirection = icicle.getInt("mNextDirection");
+        mMoveDelay = icicle.getLong("mMoveDelay");
+        mScore = icicle.getLong("mScore");
+        mSnakeTrail = coordArrayToArrayList(icicle.getIntArray("mSnakeTrail"));
+    }
+
+    /*
+     * handles key events in the game. Update the direction our snake is traveling
+     * based on the DPAD. Ignore events that would cause the snake to immediately
+     * turn back on itself.
+     * 
+     * (non-Javadoc)
+     * 
+     * @see android.view.View#onKeyDown(int, android.os.KeyEvent)
+     */
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent msg) {
+
+        if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+            if (mMode == READY | mMode == LOSE) {
+                /*
+                 * At the beginning of the game, or the end of a previous one,
+                 * we should start a new game.
+                 */
+                initNewGame();
+                setMode(RUNNING);
+                update();
+                return (true);
+            }
+
+            if (mMode == PAUSE) {
+                /*
+                 * If the game is merely paused, we should just continue where
+                 * we left off.
+                 */
+                setMode(RUNNING);
+                update();
+                return (true);
+            }
+
+            if (mDirection != SOUTH) {
+                mNextDirection = NORTH;
+            }
+            return (true);
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+            if (mDirection != NORTH) {
+                mNextDirection = SOUTH;
+            }
+            return (true);
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+            if (mDirection != EAST) {
+                mNextDirection = WEST;
+            }
+            return (true);
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+            if (mDirection != WEST) {
+                mNextDirection = EAST;
+            }
+            return (true);
+        }
+
+        return super.onKeyDown(keyCode, msg);
+    }
+
+    /**
+     * Sets the TextView that will be used to give information (such as "Game
+     * Over" to the user.
+     * 
+     * @param newView
+     */
+    public void setTextView(TextView newView) {
+        mStatusText = newView;
+    }
+
+    /**
+     * Updates the current mode of the application (RUNNING or PAUSED or the like)
+     * as well as sets the visibility of textview for notification
+     * 
+     * @param newMode
+     */
+    public void setMode(int newMode) {
+        int oldMode = mMode;
+        mMode = newMode;
+
+        if (newMode == RUNNING & oldMode != RUNNING) {
+            mStatusText.setVisibility(View.INVISIBLE);
+            update();
+            return;
+        }
+
+        Resources res = getContext().getResources();
+        CharSequence str = "";
+        if (newMode == PAUSE) {
+            str = res.getText(R.string.mode_pause);
+        }
+        if (newMode == READY) {
+            str = res.getText(R.string.mode_ready);
+        }
+        if (newMode == LOSE) {
+            str = res.getString(R.string.mode_lose_prefix) + mScore
+                  + res.getString(R.string.mode_lose_suffix);
+        }
+
+        mStatusText.setText(str);
+        mStatusText.setVisibility(View.VISIBLE);
+    }
+
+    /**
+     * Selects a random location within the garden that is not currently covered
+     * by the snake. Currently _could_ go into an infinite loop if the snake
+     * currently fills the garden, but we'll leave discovery of this prize to a
+     * truly excellent snake-player.
+     * 
+     */
+    private void addRandomApple() {
+        Coordinate newCoord = null;
+        boolean found = false;
+        while (!found) {
+            // Choose a new location for our apple
+            int newX = 1 + RNG.nextInt(mXTileCount - 2);
+            int newY = 1 + RNG.nextInt(mYTileCount - 2);
+            newCoord = new Coordinate(newX, newY);
+
+            // Make sure it's not already under the snake
+            boolean collision = false;
+            int snakelength = mSnakeTrail.size();
+            for (int index = 0; index < snakelength; index++) {
+                if (mSnakeTrail.get(index).equals(newCoord)) {
+                    collision = true;
+                }
+            }
+            // if we're here and there's been no collision, then we have
+            // a good location for an apple. Otherwise, we'll circle back
+            // and try again
+            found = !collision;
+        }
+        if (newCoord == null) {
+            Log.e(TAG, "Somehow ended up with a null newCoord!");
+        }
+        mAppleList.add(newCoord);
+    }
+
+
+    /**
+     * Handles the basic update loop, checking to see if we are in the running
+     * state, determining if a move should be made, updating the snake's location.
+     */
+    public void update() {
+        if (mMode == RUNNING) {
+            long now = System.currentTimeMillis();
+
+            if (now - mLastMove > mMoveDelay) {
+                clearTiles();
+                updateWalls();
+                updateSnake();
+                updateApples();
+                mLastMove = now;
+            }
+            mRedrawHandler.sleep(mMoveDelay);
+        }
+
+    }
+
+    /**
+     * Draws some walls.
+     * 
+     */
+    private void updateWalls() {
+        for (int x = 0; x < mXTileCount; x++) {
+            setTile(GREEN_STAR, x, 0);
+            setTile(GREEN_STAR, x, mYTileCount - 1);
+        }
+        for (int y = 1; y < mYTileCount - 1; y++) {
+            setTile(GREEN_STAR, 0, y);
+            setTile(GREEN_STAR, mXTileCount - 1, y);
+        }
+    }
+
+    /**
+     * Draws some apples.
+     * 
+     */
+    private void updateApples() {
+        for (Coordinate c : mAppleList) {
+            setTile(YELLOW_STAR, c.x, c.y);
+        }
+    }
+
+    /**
+     * Figure out which way the snake is going, see if he's run into anything (the
+     * walls, himself, or an apple). If he's not going to die, we then add to the
+     * front and subtract from the rear in order to simulate motion. If we want to
+     * grow him, we don't subtract from the rear.
+     * 
+     */
+    private void updateSnake() {
+        boolean growSnake = false;
+
+        // grab the snake by the head
+        Coordinate head = mSnakeTrail.get(0);
+        Coordinate newHead = new Coordinate(1, 1);
+
+        mDirection = mNextDirection;
+
+        switch (mDirection) {
+        case EAST: {
+            newHead = new Coordinate(head.x + 1, head.y);
+            break;
+        }
+        case WEST: {
+            newHead = new Coordinate(head.x - 1, head.y);
+            break;
+        }
+        case NORTH: {
+            newHead = new Coordinate(head.x, head.y - 1);
+            break;
+        }
+        case SOUTH: {
+            newHead = new Coordinate(head.x, head.y + 1);
+            break;
+        }
+        }
+
+        // Collision detection
+        // For now we have a 1-square wall around the entire arena
+        if ((newHead.x < 1) || (newHead.y < 1) || (newHead.x > mXTileCount - 2)
+                || (newHead.y > mYTileCount - 2)) {
+            setMode(LOSE);
+            return;
+
+        }
+
+        // Look for collisions with itself
+        int snakelength = mSnakeTrail.size();
+        for (int snakeindex = 0; snakeindex < snakelength; snakeindex++) {
+            Coordinate c = mSnakeTrail.get(snakeindex);
+            if (c.equals(newHead)) {
+                setMode(LOSE);
+                return;
+            }
+        }
+
+        // Look for apples
+        int applecount = mAppleList.size();
+        for (int appleindex = 0; appleindex < applecount; appleindex++) {
+            Coordinate c = mAppleList.get(appleindex);
+            if (c.equals(newHead)) {
+                mAppleList.remove(c);
+                addRandomApple();
+                
+                mScore++;
+                mMoveDelay *= 0.9;
+
+                growSnake = true;
+            }
+        }
+
+        // push a new head onto the ArrayList and pull off the tail
+        mSnakeTrail.add(0, newHead);
+        // except if we want the snake to grow
+        if (!growSnake) {
+            mSnakeTrail.remove(mSnakeTrail.size() - 1);
+        }
+
+        int index = 0;
+        for (Coordinate c : mSnakeTrail) {
+            if (index == 0) {
+                setTile(YELLOW_STAR, c.x, c.y);
+            } else {
+                setTile(RED_STAR, c.x, c.y);
+            }
+            index++;
+        }
+
+    }
+
+    /**
+     * Simple class containing two integer values and a comparison function.
+     * There's probably something I should use instead, but this was quick and
+     * easy to build.
+     * 
+     */
+    private class Coordinate {
+        public int x;
+        public int y;
+
+        public Coordinate(int newX, int newY) {
+            x = newX;
+            y = newY;
+        }
+
+        public boolean equals(Coordinate other) {
+            if (x == other.x && y == other.y) {
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "Coordinate: [" + x + "," + y + "]";
+        }
+    }
+    
+}
diff --git a/samples/Snake/src/com/example/android/snake/TileView.java b/samples/Snake/src/com/example/android/snake/TileView.java
new file mode 100644
index 0000000..a912c53
--- /dev/null
+++ b/samples/Snake/src/com/example/android/snake/TileView.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.snake;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+
+/**
+ * TileView: a View-variant designed for handling arrays of "icons" or other
+ * drawables.
+ * 
+ */
+public class TileView extends View {
+
+    /**
+     * Parameters controlling the size of the tiles and their range within view.
+     * Width/Height are in pixels, and Drawables will be scaled to fit to these
+     * dimensions. X/Y Tile Counts are the number of tiles that will be drawn.
+     */
+
+    protected static int mTileSize;
+
+    protected static int mXTileCount;
+    protected static int mYTileCount;
+
+    private static int mXOffset;
+    private static int mYOffset;
+
+
+    /**
+     * A hash that maps integer handles specified by the subclasser to the
+     * drawable that will be used for that reference
+     */
+    private Bitmap[] mTileArray; 
+
+    /**
+     * A two-dimensional array of integers in which the number represents the
+     * index of the tile that should be drawn at that locations
+     */
+    private int[][] mTileGrid;
+
+    private final Paint mPaint = new Paint();
+
+    public TileView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView);
+
+        mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);
+        
+        a.recycle();
+    }
+
+    public TileView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView);
+
+        mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);
+        
+        a.recycle();
+    }
+
+    
+    
+    /**
+     * Rests the internal array of Bitmaps used for drawing tiles, and
+     * sets the maximum index of tiles to be inserted
+     * 
+     * @param tilecount
+     */
+    
+    public void resetTiles(int tilecount) {
+    	mTileArray = new Bitmap[tilecount];
+    }
+
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        mXTileCount = (int) Math.floor(w / mTileSize);
+        mYTileCount = (int) Math.floor(h / mTileSize);
+
+        mXOffset = ((w - (mTileSize * mXTileCount)) / 2);
+        mYOffset = ((h - (mTileSize * mYTileCount)) / 2);
+
+        mTileGrid = new int[mXTileCount][mYTileCount];
+        clearTiles();
+    }
+
+    /**
+     * Function to set the specified Drawable as the tile for a particular
+     * integer key.
+     * 
+     * @param key
+     * @param tile
+     */
+    public void loadTile(int key, Drawable tile) {
+        Bitmap bitmap = Bitmap.createBitmap(mTileSize, mTileSize, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+        tile.setBounds(0, 0, mTileSize, mTileSize);
+        tile.draw(canvas);
+        
+        mTileArray[key] = bitmap;
+    }
+
+    /**
+     * Resets all tiles to 0 (empty)
+     * 
+     */
+    public void clearTiles() {
+        for (int x = 0; x < mXTileCount; x++) {
+            for (int y = 0; y < mYTileCount; y++) {
+                setTile(0, x, y);
+            }
+        }
+    }
+
+    /**
+     * Used to indicate that a particular tile (set with loadTile and referenced
+     * by an integer) should be drawn at the given x/y coordinates during the
+     * next invalidate/draw cycle.
+     * 
+     * @param tileindex
+     * @param x
+     * @param y
+     */
+    public void setTile(int tileindex, int x, int y) {
+        mTileGrid[x][y] = tileindex;
+    }
+
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        for (int x = 0; x < mXTileCount; x += 1) {
+            for (int y = 0; y < mYTileCount; y += 1) {
+                if (mTileGrid[x][y] > 0) {
+                    canvas.drawBitmap(mTileArray[mTileGrid[x][y]], 
+                    		mXOffset + x * mTileSize,
+                    		mYOffset + y * mTileSize,
+                    		mPaint);
+                }
+            }
+        }
+
+    }
+
+}
diff --git a/samples/Snake/tests/Android.mk b/samples/Snake/tests/Android.mk
new file mode 100644
index 0000000..3d16805
--- /dev/null
+++ b/samples/Snake/tests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := SnakeTests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_INSTRUMENTATION_FOR := Snake
+
+include $(BUILD_PACKAGE)
diff --git a/samples/Snake/tests/AndroidManifest.xml b/samples/Snake/tests/AndroidManifest.xml
new file mode 100644
index 0000000..382506c
--- /dev/null
+++ b/samples/Snake/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.snake.tests">
+    
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+  <instrumentation android:name="android.test.InstrumentationTestRunner"
+      android:targetPackage="com.example.android.snake"
+      android:label="Snake sample tests">
+  </instrumentation>  
+  
+</manifest>
diff --git a/samples/Snake/tests/src/com/example/android/snake/SnakeTest.java b/samples/Snake/tests/src/com/example/android/snake/SnakeTest.java
new file mode 100644
index 0000000..35d1b12
--- /dev/null
+++ b/samples/Snake/tests/src/com/example/android/snake/SnakeTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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.snake;
+
+import android.test.ActivityInstrumentationTestCase;
+
+import com.example.android.snake.Snake;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class SnakeTest extends ActivityInstrumentationTestCase<Snake> {
+  
+  public SnakeTest() {
+      super("com.example.android.snake", Snake.class);
+  }
+  
+}
diff --git a/samples/SoftKeyboard/Android.mk b/samples/SoftKeyboard/Android.mk
new file mode 100755
index 0000000..883bf2f
--- /dev/null
+++ b/samples/SoftKeyboard/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 := SoftKeyboard
+
+include $(BUILD_PACKAGE)
diff --git a/samples/SoftKeyboard/AndroidManifest.xml b/samples/SoftKeyboard/AndroidManifest.xml
new file mode 100755
index 0000000..61b5131
--- /dev/null
+++ b/samples/SoftKeyboard/AndroidManifest.xml
@@ -0,0 +1,12 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
+        package="com.example.android.softkeyboard">
+    <application android:label="@string/ime_name">
+        <service android:name="SoftKeyboard"
+                android:permission="android.permission.BIND_INPUT_METHOD">
+            <intent-filter>
+                <action android:name="android.view.InputMethod" />
+            </intent-filter>
+            <meta-data android:name="android.view.im" android:resource="@xml/method" />
+        </service>
+    </application>
+</manifest>
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_delete.png b/samples/SoftKeyboard/res/drawable/sym_keyboard_delete.png
new file mode 100644
index 0000000..6cee596
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable/sym_keyboard_delete.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_done.png b/samples/SoftKeyboard/res/drawable/sym_keyboard_done.png
new file mode 100755
index 0000000..c0d6d13
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable/sym_keyboard_done.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_return.png b/samples/SoftKeyboard/res/drawable/sym_keyboard_return.png
new file mode 100644
index 0000000..cbe2b15
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable/sym_keyboard_return.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_search.png b/samples/SoftKeyboard/res/drawable/sym_keyboard_search.png
new file mode 100755
index 0000000..127755d
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable/sym_keyboard_search.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_shift.png b/samples/SoftKeyboard/res/drawable/sym_keyboard_shift.png
new file mode 100644
index 0000000..d059628
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable/sym_keyboard_shift.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_space.png b/samples/SoftKeyboard/res/drawable/sym_keyboard_space.png
new file mode 100644
index 0000000..09b94d9
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable/sym_keyboard_space.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/layout/input.xml b/samples/SoftKeyboard/res/layout/input.xml
new file mode 100755
index 0000000..1b57468
--- /dev/null
+++ b/samples/SoftKeyboard/res/layout/input.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<com.example.android.softkeyboard.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/keyboard"
+        android:layout_alignParentBottom="true"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        />
diff --git a/samples/SoftKeyboard/res/values-land/dimens.xml b/samples/SoftKeyboard/res/values-land/dimens.xml
new file mode 100644
index 0000000..b5f3bc1
--- /dev/null
+++ b/samples/SoftKeyboard/res/values-land/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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="key_height">46dip</dimen>
+</resources>
diff --git a/samples/SoftKeyboard/res/values/colors.xml b/samples/SoftKeyboard/res/values/colors.xml
new file mode 100644
index 0000000..74d103a
--- /dev/null
+++ b/samples/SoftKeyboard/res/values/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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="candidate_normal">#FF000000</color>
+    <color name="candidate_recommended">#FFE35900</color>
+    <color name="candidate_other">#ff808080</color>
+    <color name="candidate_background">#bbffffff</color>
+</resources>
\ No newline at end of file
diff --git a/samples/SoftKeyboard/res/values/dimens.xml b/samples/SoftKeyboard/res/values/dimens.xml
new file mode 100644
index 0000000..caf615c
--- /dev/null
+++ b/samples/SoftKeyboard/res/values/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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="key_height">50dip</dimen>
+    <dimen name="candidate_font_height">16sp</dimen>
+    <dimen name="candidate_vertical_padding">6sp</dimen>
+</resources>
\ No newline at end of file
diff --git a/samples/SoftKeyboard/res/values/strings.xml b/samples/SoftKeyboard/res/values/strings.xml
new file mode 100644
index 0000000..bc645b2
--- /dev/null
+++ b/samples/SoftKeyboard/res/values/strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Title for Latin keyboard  -->
+    <string name="ime_name">Sample Soft Keyboard</string>
+
+    <!-- Symbols that are commonly considered word separators in this language -->
+    <string name="word_separators">\u0020.,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|&quot;</string>
+    
+    <!-- Labels on soft keys -->
+    <string name="label_go_key">Go</string>
+    <string name="label_next_key">Next</string>
+    <string name="label_send_key">Send</string>
+</resources>
diff --git a/samples/SoftKeyboard/res/xml/method.xml b/samples/SoftKeyboard/res/xml/method.xml
new file mode 100644
index 0000000..d246624
--- /dev/null
+++ b/samples/SoftKeyboard/res/xml/method.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2008, 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 configuration information -->
+<!-- for the Search Manager. -->
+
+<input-method xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/samples/SoftKeyboard/res/xml/qwerty.xml b/samples/SoftKeyboard/res/xml/qwerty.xml
new file mode 100755
index 0000000..e81d9f1
--- /dev/null
+++ b/samples/SoftKeyboard/res/xml/qwerty.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:keyWidth="10%p"
+    android:horizontalGap="0px"
+    android:verticalGap="0px"
+    android:keyHeight="@dimen/key_height"
+    >
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+    
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p" 
+                android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
+    </Row>
+    
+    <Row>
+        <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift" 
+                android:keyWidth="15%p" android:isModifier="true"
+                android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" android:keyLabel="m"/>
+        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete" 
+                android:keyWidth="15%p" android:keyEdgeFlags="right"
+                android:isRepeatable="true"/>
+    </Row>
+    
+    <Row android:rowEdgeFlags="bottom">
+        <Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done" 
+                android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+        <Key android:codes="-2" android:keyLabel="123" android:keyWidth="15%p"/>
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" 
+                android:keyWidth="30%p" android:isRepeatable="true"/>
+        <Key android:codes="46,44" android:keyLabel=". ,"
+                android:keyWidth="15%p"/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" 
+                android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+    </Row>
+</Keyboard>
+    
\ No newline at end of file
diff --git a/samples/SoftKeyboard/res/xml/symbols.xml b/samples/SoftKeyboard/res/xml/symbols.xml
new file mode 100755
index 0000000..a28d752
--- /dev/null
+++ b/samples/SoftKeyboard/res/xml/symbols.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:keyWidth="10%p"
+    android:horizontalGap="0px"
+    android:verticalGap="0px"
+    android:keyHeight="@dimen/key_height"
+    >
+
+    <Row>
+        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:codes="50" android:keyLabel="2"/>
+        <Key android:codes="51" android:keyLabel="3"/>
+        <Key android:codes="52" android:keyLabel="4"/>
+        <Key android:codes="53" android:keyLabel="5"/>
+        <Key android:codes="54" android:keyLabel="6"/>
+        <Key android:codes="55" android:keyLabel="7"/>
+        <Key android:codes="56" android:keyLabel="8"/>
+        <Key android:codes="57" android:keyLabel="9"/>
+        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
+    </Row>
+    
+    <Row>
+        <Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/>
+        <Key android:codes="35" android:keyLabel="\#"/>
+        <Key android:codes="36" android:keyLabel="$"/>
+        <Key android:codes="37" android:keyLabel="%"/>
+        <Key android:codes="38" android:keyLabel="&amp;"/>
+        <Key android:codes="42" android:keyLabel="*"/>
+        <Key android:codes="45" android:keyLabel="-"/>
+        <Key android:codes="61" android:keyLabel="="/>
+        <Key android:codes="40" android:keyLabel="("/>
+        <Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right"/>
+    </Row>
+    
+    <Row>
+        <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
+                android:keyWidth="15%p" android:isModifier="true"
+                android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:codes="33" android:keyLabel="!" />
+        <Key android:codes="34" android:keyLabel="&quot;"/>
+        <Key android:codes="39" android:keyLabel="\'"/>
+        <Key android:codes="58" android:keyLabel=":"/>
+        <Key android:codes="59" android:keyLabel=";"/>
+        <Key android:codes="47" android:keyLabel="/" />
+        <Key android:codes="63" android:keyLabel="\?"/>
+        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+                android:keyWidth="15%p" android:keyEdgeFlags="right"
+                android:isRepeatable="true"/>
+    </Row>
+    
+    <Row  android:rowEdgeFlags="bottom">
+        <Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done"
+                android:keyWidth="20%p" android:keyEdgeFlags="left" />
+        <Key android:codes="-2" android:keyLabel="ABC" android:keyWidth="15%p" />
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" android:keyWidth="30%p" 
+                android:isRepeatable="true"/>
+        <Key android:codes="44" android:keyLabel="," android:keyWidth="15%p" />
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+                android:keyWidth="20%p" android:keyEdgeFlags="right"
+                />
+    </Row>
+</Keyboard>
\ No newline at end of file
diff --git a/samples/SoftKeyboard/res/xml/symbols_shift.xml b/samples/SoftKeyboard/res/xml/symbols_shift.xml
new file mode 100755
index 0000000..d7139f3
--- /dev/null
+++ b/samples/SoftKeyboard/res/xml/symbols_shift.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* 
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:keyWidth="10%p"
+    android:horizontalGap="0px"
+    android:verticalGap="0px"
+    android:keyHeight="@dimen/key_height"
+    >
+
+    <Row>
+        <Key android:codes="126" android:keyLabel="~" android:keyEdgeFlags="left"/>
+        <Key android:codes="177" android:keyLabel="±"/>
+        <Key android:codes="215" android:keyLabel="×"/>
+        <Key android:codes="247" android:keyLabel="÷"/>
+        <Key android:codes="8226" android:keyLabel="•"/>
+        <Key android:codes="176" android:keyLabel="°"/>
+        <Key android:codes="96" android:keyLabel="`"/>
+        <Key android:codes="180" android:keyLabel="´"/>
+        <Key android:codes="123" android:keyLabel="{"/>
+        <Key android:codes="125" android:keyLabel="}" android:keyEdgeFlags="right"/>
+    </Row>
+    
+    <Row>
+        <Key android:codes="169" android:keyLabel="©" android:keyEdgeFlags="left"/>
+        <Key android:codes="163" android:keyLabel="£"/>
+        <Key android:codes="8364" android:keyLabel="€"/>
+        <Key android:codes="94" android:keyLabel="^"/>
+        <Key android:codes="174" android:keyLabel="®"/>
+        <Key android:codes="165" android:keyLabel="¥"/>
+        <Key android:codes="95" android:keyLabel="_"/>
+        <Key android:codes="43" android:keyLabel="+"/>
+        <Key android:codes="91" android:keyLabel="["/>
+        <Key android:codes="93" android:keyLabel="]" android:keyEdgeFlags="right"/>
+    </Row>
+    
+    <Row>
+        <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
+                android:keyWidth="15%p" android:isModifier="true"
+                android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:codes="161" android:keyLabel="¡" />
+        <Key android:codes="60" android:keyLabel="&lt;"/>
+        <Key android:codes="62" android:keyLabel="&gt;"/>
+        <Key android:codes="162" android:keyLabel="¢"/>
+        <Key android:codes="124" android:keyLabel="|"/>
+        <Key android:codes="92" android:keyLabel="\\" />
+        <Key android:codes="191" android:keyLabel="¿"/>
+        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+                android:keyWidth="15%p" android:keyEdgeFlags="right"
+                android:isRepeatable="true"/>
+    </Row>
+    
+    <Row android:rowEdgeFlags="bottom">
+        <Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done" 
+                android:keyWidth="20%p" android:keyEdgeFlags="left" />
+        <Key android:codes="-2" android:keyLabel="ABC" android:keyWidth="15%p" />
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" android:keyWidth="30%p" 
+                android:isRepeatable="true"/>
+        <Key android:codes="8230" android:keyLabel="…" android:keyWidth="15%p" />
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+                android:keyWidth="20%p" android:keyEdgeFlags="right" />
+    </Row>
+</Keyboard>
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java
new file mode 100755
index 0000000..7cadead
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ * 
+ * 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.softkeyboard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CandidateView extends View {
+
+    private static final int OUT_OF_BOUNDS = -1;
+
+    private SoftKeyboard mService;
+    private List<String> mSuggestions;
+    private int mSelectedIndex;
+    private int mTouchX = OUT_OF_BOUNDS;
+    private Drawable mSelectionHighlight;
+    private boolean mTypedWordValid;
+    
+    private Rect mBgPadding;
+
+    private static final int MAX_SUGGESTIONS = 32;
+    private static final int SCROLL_PIXELS = 20;
+    
+    private int[] mWordWidth = new int[MAX_SUGGESTIONS];
+    private int[] mWordX = new int[MAX_SUGGESTIONS];
+
+    private static final int X_GAP = 10;
+    
+    private static final List<String> EMPTY_LIST = new ArrayList<String>();
+
+    private int mColorNormal;
+    private int mColorRecommended;
+    private int mColorOther;
+    private int mVerticalPadding;
+    private Paint mPaint;
+    private boolean mScrolled;
+    private int mTargetScrollX;
+    
+    private int mTotalWidth;
+    
+    private GestureDetector mGestureDetector;
+
+    /**
+     * Construct a CandidateView for showing suggested words for completion.
+     * @param context
+     * @param attrs
+     */
+    public CandidateView(Context context) {
+        super(context);
+        mSelectionHighlight = context.getResources().getDrawable(
+                android.R.drawable.list_selector_background);
+        mSelectionHighlight.setState(new int[] {
+                android.R.attr.state_enabled,
+                android.R.attr.state_focused,
+                android.R.attr.state_window_focused,
+                android.R.attr.state_pressed
+        });
+
+        Resources r = context.getResources();
+        
+        setBackgroundColor(r.getColor(R.color.candidate_background));
+        
+        mColorNormal = r.getColor(R.color.candidate_normal);
+        mColorRecommended = r.getColor(R.color.candidate_recommended);
+        mColorOther = r.getColor(R.color.candidate_other);
+        mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding);
+        
+        mPaint = new Paint();
+        mPaint.setColor(mColorNormal);
+        mPaint.setAntiAlias(true);
+        mPaint.setTextSize(r.getDimensionPixelSize(R.dimen.candidate_font_height));
+        mPaint.setStrokeWidth(0);
+        
+        mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
+            @Override
+            public boolean onScroll(MotionEvent e1, MotionEvent e2,
+                    float distanceX, float distanceY) {
+                mScrolled = true;
+                int sx = getScrollX();
+                sx += distanceX;
+                if (sx < 0) {
+                    sx = 0;
+                }
+                if (sx + getWidth() > mTotalWidth) {                    
+                    sx -= distanceX;
+                }
+                mTargetScrollX = sx;
+                scrollTo(sx, getScrollY());
+                invalidate();
+                return true;
+            }
+        });
+        setHorizontalFadingEdgeEnabled(true);
+        setWillNotDraw(false);
+        setHorizontalScrollBarEnabled(false);
+        setVerticalScrollBarEnabled(false);
+    }
+    
+    /**
+     * A connection back to the service to communicate with the text field
+     * @param listener
+     */
+    public void setService(SoftKeyboard listener) {
+        mService = listener;
+    }
+    
+    @Override
+    public int computeHorizontalScrollRange() {
+        return mTotalWidth;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int measuredWidth = resolveSize(50, widthMeasureSpec);
+        
+        // Get the desired height of the icon menu view (last row of items does
+        // not have a divider below)
+        Rect padding = new Rect();
+        mSelectionHighlight.getPadding(padding);
+        final int desiredHeight = ((int)mPaint.getTextSize()) + mVerticalPadding
+                + padding.top + padding.bottom;
+        
+        // Maximum possible width and desired height
+        setMeasuredDimension(measuredWidth,
+                resolveSize(desiredHeight, heightMeasureSpec));
+    }
+
+    /**
+     * If the canvas is null, then only touch calculations are performed to pick the target
+     * candidate.
+     */
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (canvas != null) {
+            super.onDraw(canvas);
+        }
+        mTotalWidth = 0;
+        if (mSuggestions == null) return;
+        
+        if (mBgPadding == null) {
+            mBgPadding = new Rect(0, 0, 0, 0);
+            if (getBackground() != null) {
+                getBackground().getPadding(mBgPadding);
+            }
+        }
+        int x = 0;
+        final int count = mSuggestions.size(); 
+        final int height = getHeight();
+        final Rect bgPadding = mBgPadding;
+        final Paint paint = mPaint;
+        final int touchX = mTouchX;
+        final int scrollX = getScrollX();
+        final boolean scrolled = mScrolled;
+        final boolean typedWordValid = mTypedWordValid;
+        final int y = (int) (((height - mPaint.getTextSize()) / 2) - mPaint.ascent());
+
+        for (int i = 0; i < count; i++) {
+            String suggestion = mSuggestions.get(i);
+            float textWidth = paint.measureText(suggestion);
+            final int wordWidth = (int) textWidth + X_GAP * 2;
+
+            mWordX[i] = x;
+            mWordWidth[i] = wordWidth;
+            paint.setColor(mColorNormal);
+            if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled) {
+                if (canvas != null) {
+                    canvas.translate(x, 0);
+                    mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height);
+                    mSelectionHighlight.draw(canvas);
+                    canvas.translate(-x, 0);
+                }
+                mSelectedIndex = i;
+            }
+
+            if (canvas != null) {
+                if ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid)) {
+                    paint.setFakeBoldText(true);
+                    paint.setColor(mColorRecommended);
+                } else if (i != 0) {
+                    paint.setColor(mColorOther);
+                }
+                canvas.drawText(suggestion, x + X_GAP, y, paint);
+                paint.setColor(mColorOther); 
+                canvas.drawLine(x + wordWidth + 0.5f, bgPadding.top, 
+                        x + wordWidth + 0.5f, height + 1, paint);
+                paint.setFakeBoldText(false);
+            }
+            x += wordWidth;
+        }
+        mTotalWidth = x;
+        if (mTargetScrollX != getScrollX()) {
+            scrollToTarget();
+        }
+    }
+    
+    private void scrollToTarget() {
+        int sx = getScrollX();
+        if (mTargetScrollX > sx) {
+            sx += SCROLL_PIXELS;
+            if (sx >= mTargetScrollX) {
+                sx = mTargetScrollX;
+                requestLayout();
+            }
+        } else {
+            sx -= SCROLL_PIXELS;
+            if (sx <= mTargetScrollX) {
+                sx = mTargetScrollX;
+                requestLayout();
+            }
+        }
+        scrollTo(sx, getScrollY());
+        invalidate();
+    }
+    
+    public void setSuggestions(List<String> suggestions, boolean completions,
+            boolean typedWordValid) {
+        clear();
+        if (suggestions != null) {
+            mSuggestions = new ArrayList<String>(suggestions);
+        }
+        mTypedWordValid = typedWordValid;
+        scrollTo(0, 0);
+        mTargetScrollX = 0;
+        // Compute the total width
+        onDraw(null);
+        invalidate();
+        requestLayout();
+    }
+
+    public void clear() {
+        mSuggestions = EMPTY_LIST;
+        mTouchX = OUT_OF_BOUNDS;
+        mSelectedIndex = -1;
+        invalidate();
+    }
+    
+    @Override
+    public boolean onTouchEvent(MotionEvent me) {
+
+        if (mGestureDetector.onTouchEvent(me)) {
+            return true;
+        }
+
+        int action = me.getAction();
+        int x = (int) me.getX();
+        int y = (int) me.getY();
+        mTouchX = x;
+
+        switch (action) {
+        case MotionEvent.ACTION_DOWN:
+            mScrolled = false;
+            invalidate();
+            break;
+        case MotionEvent.ACTION_MOVE:
+            if (y <= 0) {
+                // Fling up!?
+                if (mSelectedIndex >= 0) {
+                    mService.pickSuggestionManually(mSelectedIndex);
+                    mSelectedIndex = -1;
+                }
+            }
+            invalidate();
+            break;
+        case MotionEvent.ACTION_UP:
+            if (!mScrolled) {
+                if (mSelectedIndex >= 0) {
+                    mService.pickSuggestionManually(mSelectedIndex);
+                }
+            }
+            mSelectedIndex = -1;
+            removeHighlight();
+            requestLayout();
+            break;
+        }
+        return true;
+    }
+    
+    /**
+     * For flick through from keyboard, call this method with the x coordinate of the flick 
+     * gesture.
+     * @param x
+     */
+    public void takeSuggestionAt(float x) {
+        mTouchX = (int) x;
+        // To detect candidate
+        onDraw(null);
+        if (mSelectedIndex >= 0) {
+            mService.pickSuggestionManually(mSelectedIndex);
+        }
+        invalidate();
+    }
+
+    private void removeHighlight() {
+        mTouchX = OUT_OF_BOUNDS;
+        invalidate();
+    }
+}
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java
new file mode 100644
index 0000000..1798442
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ * 
+ * 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.softkeyboard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.Keyboard.Key;
+import android.inputmethodservice.Keyboard.Row;
+import android.view.inputmethod.EditorInfo;
+
+public class LatinKeyboard extends Keyboard {
+
+    private Key mEnterKey;
+    
+    public LatinKeyboard(Context context, int xmlLayoutResId) {
+        super(context, xmlLayoutResId);
+    }
+
+    public LatinKeyboard(Context context, int layoutTemplateResId, 
+            CharSequence characters, int columns, int horizontalPadding) {
+        super(context, layoutTemplateResId, characters, columns, horizontalPadding);
+    }
+
+    @Override
+    protected Key createKeyFromXml(Resources res, Row parent, int x, int y, 
+            XmlResourceParser parser) {
+        Key key = new LatinKey(res, parent, x, y, parser);
+        if (key.codes[0] == 10) {
+            mEnterKey = key;
+        }
+        return key;
+    }
+    
+    /**
+     * This looks at the ime options given by the current editor, to set the
+     * appropriate label on the keyboard's enter key (if it has one).
+     */
+    void setImeOptions(Resources res, int options) {
+        if (mEnterKey == null) {
+            return;
+        }
+        
+        switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) {
+            case EditorInfo.IME_ACTION_GO:
+                mEnterKey.iconPreview = null;
+                mEnterKey.icon = null;
+                mEnterKey.label = res.getText(R.string.label_go_key);
+                break;
+            case EditorInfo.IME_ACTION_NEXT:
+                mEnterKey.iconPreview = null;
+                mEnterKey.icon = null;
+                mEnterKey.label = res.getText(R.string.label_next_key);
+                break;
+            case EditorInfo.IME_ACTION_SEARCH:
+                mEnterKey.icon = res.getDrawable(
+                        R.drawable.sym_keyboard_search);
+                mEnterKey.label = null;
+                break;
+            case EditorInfo.IME_ACTION_SEND:
+                mEnterKey.iconPreview = null;
+                mEnterKey.icon = null;
+                mEnterKey.label = res.getText(R.string.label_send_key);
+                break;
+            default:
+                mEnterKey.icon = res.getDrawable(
+                        R.drawable.sym_keyboard_return);
+                mEnterKey.label = null;
+                break;
+        }
+    }
+    
+    static class LatinKey extends Keyboard.Key {
+        
+        public LatinKey(Resources res, Keyboard.Row parent, int x, int y, XmlResourceParser parser) {
+            super(res, parent, x, y, parser);
+        }
+        
+        /**
+         * Overriding this method so that we can reduce the target area for the key that
+         * closes the keyboard. 
+         */
+        @Override
+        public boolean isInside(int x, int y) {
+            return super.isInside(x, codes[0] == KEYCODE_CANCEL ? y - 10 : y);
+        }
+    }
+
+}
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java
new file mode 100644
index 0000000..7464607
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ * 
+ * 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.softkeyboard;
+
+import android.content.Context;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.KeyboardView;
+import android.inputmethodservice.Keyboard.Key;
+import android.util.AttributeSet;
+
+public class LatinKeyboardView extends KeyboardView {
+
+    static final int KEYCODE_OPTIONS = -100;
+
+    public LatinKeyboardView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected boolean onLongPress(Key key) {
+        if (key.codes[0] == Keyboard.KEYCODE_CANCEL) {
+            getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null);
+            return true;
+        } else {
+            return super.onLongPress(key);
+        }
+    }
+}
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
new file mode 100644
index 0000000..656efdf
--- /dev/null
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
@@ -0,0 +1,674 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ * 
+ * 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.softkeyboard;
+
+import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.KeyboardView;
+import android.text.method.MetaKeyKeyListener;
+import android.util.Log;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Example of writing an input method for a soft keyboard.  This code is
+ * focused on simplicity over completeness, so it should in no way be considered
+ * to be a complete soft keyboard implementation.  Its purpose is to provide
+ * a basic example for how you would get started writing an input method, to
+ * be fleshed out as appropriate.
+ */
+public class SoftKeyboard extends InputMethodService 
+        implements KeyboardView.OnKeyboardActionListener {
+    static final boolean DEBUG = false;
+    
+    /**
+     * This boolean indicates the optional example code for performing
+     * processing of hard keys in addition to regular text generation
+     * from on-screen interaction.  It would be used for input methods that
+     * perform language translations (such as converting text entered on 
+     * a QWERTY keyboard to Chinese), but may not be used for input methods
+     * that are primarily intended to be used for on-screen text entry.
+     */
+    static final boolean PROCESS_HARD_KEYS = true;
+    
+    private KeyboardView mInputView;
+    private CandidateView mCandidateView;
+    private CompletionInfo[] mCompletions;
+    
+    private StringBuilder mComposing = new StringBuilder();
+    private boolean mPredictionOn;
+    private boolean mCompletionOn;
+    private int mLastDisplayWidth;
+    private boolean mCapsLock;
+    private long mLastShiftTime;
+    private long mMetaState;
+    
+    private LatinKeyboard mSymbolsKeyboard;
+    private LatinKeyboard mSymbolsShiftedKeyboard;
+    private LatinKeyboard mQwertyKeyboard;
+    
+    private LatinKeyboard mCurKeyboard;
+    
+    private String mWordSeparators;
+    
+    /**
+     * Main initialization of the input method component.  Be sure to call
+     * to super class.
+     */
+    @Override public void onCreate() {
+        super.onCreate();
+        mWordSeparators = getResources().getString(R.string.word_separators);
+    }
+    
+    /**
+     * This is the point where you can do all of your UI initialization.  It
+     * is called after creation and any configuration change.
+     */
+    @Override public void onInitializeInterface() {
+        if (mQwertyKeyboard != null) {
+            // Configuration changes can happen after the keyboard gets recreated,
+            // so we need to be able to re-build the keyboards if the available
+            // space has changed.
+            int displayWidth = getMaxWidth();
+            if (displayWidth == mLastDisplayWidth) return;
+            mLastDisplayWidth = displayWidth;
+        }
+        mQwertyKeyboard = new LatinKeyboard(this, R.xml.qwerty);
+        mSymbolsKeyboard = new LatinKeyboard(this, R.xml.symbols);
+        mSymbolsShiftedKeyboard = new LatinKeyboard(this, R.xml.symbols_shift);
+    }
+    
+    /**
+     * Called by the framework when your view for creating input needs to
+     * be generated.  This will be called the first time your input method
+     * is displayed, and every time it needs to be re-created such as due to
+     * a configuration change.
+     */
+    @Override public View onCreateInputView() {
+        mInputView = (KeyboardView) getLayoutInflater().inflate(
+                R.layout.input, null);
+        mInputView.setOnKeyboardActionListener(this);
+        mInputView.setKeyboard(mQwertyKeyboard);
+        return mInputView;
+    }
+
+    /**
+     * Called by the framework when your view for showing candidates needs to
+     * be generated, like {@link #onCreateInputView}.
+     */
+    @Override public View onCreateCandidatesView() {
+        mCandidateView = new CandidateView(this);
+        mCandidateView.setService(this);
+        return mCandidateView;
+    }
+
+    /**
+     * This is the main point where we do our initialization of the input method
+     * to begin operating on an application.  At this point we have been
+     * bound to the client, and are now receiving all of the detailed information
+     * about the target of our edits.
+     */
+    @Override public void onStartInput(EditorInfo attribute, boolean restarting) {
+        super.onStartInput(attribute, restarting);
+        
+        // Reset our state.  We want to do this even if restarting, because
+        // the underlying state of the text editor could have changed in any way.
+        mComposing.setLength(0);
+        updateCandidates();
+        
+        if (!restarting) {
+            // Clear shift states.
+            mMetaState = 0;
+        }
+        
+        mPredictionOn = false;
+        mCompletionOn = false;
+        mCompletions = null;
+        
+        // We are now going to initialize our state based on the type of
+        // text being edited.
+        switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) {
+            case EditorInfo.TYPE_CLASS_NUMBER:
+            case EditorInfo.TYPE_CLASS_DATETIME:
+                // Numbers and dates default to the symbols keyboard, with
+                // no extra features.
+                mCurKeyboard = mSymbolsKeyboard;
+                break;
+                
+            case EditorInfo.TYPE_CLASS_PHONE:
+                // Phones will also default to the symbols keyboard, though
+                // often you will want to have a dedicated phone keyboard.
+                mCurKeyboard = mSymbolsKeyboard;
+                break;
+                
+            case EditorInfo.TYPE_CLASS_TEXT:
+                // This is general text editing.  We will default to the
+                // normal alphabetic keyboard, and assume that we should
+                // be doing predictive text (showing candidates as the
+                // user types).
+                mCurKeyboard = mQwertyKeyboard;
+                mPredictionOn = true;
+                
+                // We now look for a few special variations of text that will
+                // modify our behavior.
+                int variation = attribute.inputType &  EditorInfo.TYPE_MASK_VARIATION;
+                if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD) {
+                    // Do not display predictions / what the user is typing
+                    // when they are entering a password.
+                    mPredictionOn = false;
+                }
+                
+                if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS 
+                        || variation == EditorInfo.TYPE_TEXT_VARIATION_URI) {
+                    // Our predictions are not useful for e-mail addresses
+                    // or URIs.
+                    mPredictionOn = false;
+                }
+                
+                if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
+                    // If this is an auto-complete text view, then our predictions
+                    // will not be shown and instead we will allow the editor
+                    // to supply their own.  We only show the editor's
+                    // candidates when in fullscreen mode, otherwise relying
+                    // own it displaying its own UI.
+                    mPredictionOn = false;
+                    mCompletionOn = isFullscreenMode();
+                }
+                
+                // We also want to look at the current state of the editor
+                // to decide whether our alphabetic keyboard should start out
+                // shifted.
+                updateShiftKeyState(attribute);
+                break;
+                
+            default:
+                // For all unknown input types, default to the alphabetic
+                // keyboard with no special features.
+                mCurKeyboard = mQwertyKeyboard;
+        }
+        
+        // Update the label on the enter key, depending on what the application
+        // says it will do.
+        mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
+    }
+
+    /**
+     * This is called when the user is done editing a field.  We can use
+     * this to reset our state.
+     */
+    @Override public void onFinishInput() {
+        super.onFinishInput();
+        
+        // Clear current composing text and candidates.
+        mComposing.setLength(0);
+        updateCandidates();
+        
+        // We only hide the candidates window when finishing input on
+        // a particular editor, to avoid popping the underlying application
+        // up and down if the user is entering text into the bottom of
+        // its window.
+        setCandidatesViewShown(false);
+        
+        mCurKeyboard = mQwertyKeyboard;
+        if (mInputView != null) {
+            mInputView.closing();
+        }
+    }
+    
+    @Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
+        super.onStartInputView(attribute, restarting);
+        // Apply the selected keyboard to the input view.
+        mInputView.setKeyboard(mCurKeyboard);
+        mInputView.closing();
+    }
+    
+    /**
+     * Deal with the editor reporting movement of its cursor.
+     */
+    @Override public void onUpdateSelection(int oldSelStart, int oldSelEnd,
+            int newSelStart, int newSelEnd,
+            int candidatesStart, int candidatesEnd) {
+        
+        // If the current selection in the text view changes, we should
+        // clear whatever candidate text we have.
+        if (mComposing.length() > 0 && (newSelStart != candidatesEnd
+                || newSelEnd != candidatesEnd)) {
+            mComposing.setLength(0);
+            updateCandidates();
+            InputConnection ic = getCurrentInputConnection();
+            if (ic != null) {
+                ic.finishComposingText();
+            }
+        }
+    }
+
+    /**
+     * This tells us about completions that the editor has determined based
+     * on the current text in it.  We want to use this in fullscreen mode
+     * to show the completions ourself, since the editor can not be seen
+     * in that situation.
+     */
+    @Override public void onDisplayCompletions(CompletionInfo[] completions) {
+        if (mCompletionOn) {
+            mCompletions = completions;
+            if (completions == null) {
+                setSuggestions(null, false, false);
+                return;
+            }
+            
+            List<String> stringList = new ArrayList<String>();
+            for (int i=0; i<(completions != null ? completions.length : 0); i++) {
+                CompletionInfo ci = completions[i];
+                if (ci != null) stringList.add(ci.getText().toString());
+            }
+            setSuggestions(stringList, true, true);
+        }
+    }
+    
+    /**
+     * This translates incoming hard key events in to edit operations on an
+     * InputConnection.  It is only needed when using the
+     * PROCESS_HARD_KEYS option.
+     */
+    private boolean translateKeyDown(int keyCode, KeyEvent event) {
+        mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
+                keyCode, event);
+        int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState));
+        mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
+        InputConnection ic = getCurrentInputConnection();
+        if (c == 0 || ic == null) {
+            return false;
+        }
+        
+        boolean dead = false;
+
+        if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
+            dead = true;
+            c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
+        }
+        
+        if (mComposing.length() > 0) {
+            char accent = mComposing.charAt(mComposing.length() -1 );
+            int composed = KeyEvent.getDeadChar(accent, c);
+
+            if (composed != 0) {
+                c = composed;
+                mComposing.setLength(mComposing.length()-1);
+            }
+        }
+        
+        onKey(c, null);
+        
+        return true;
+    }
+    
+    /**
+     * Use this to monitor key events being delivered to the application.
+     * We get first crack at them, and can either resume them or let them
+     * continue to the app.
+     */
+    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_BACK:
+                // The InputMethodService already takes care of the back
+                // key for us, to dismiss the input method if it is shown.
+                // However, our keyboard could be showing a pop-up window
+                // that back should dismiss, so we first allow it to do that.
+                if (event.getRepeatCount() == 0 && mInputView != null) {
+                    if (mInputView.handleBack()) {
+                        return true;
+                    }
+                }
+                break;
+                
+            case KeyEvent.KEYCODE_DEL:
+                // Special handling of the delete key: if we currently are
+                // composing text for the user, we want to modify that instead
+                // of let the application to the delete itself.
+                if (mComposing.length() > 0) {
+                    onKey(Keyboard.KEYCODE_DELETE, null);
+                    return true;
+                }
+                break;
+                
+            case KeyEvent.KEYCODE_ENTER:
+                // Let the underlying text editor always handle these.
+                return false;
+                
+            default:
+                // For all other keys, if we want to do transformations on
+                // text being entered with a hard keyboard, we need to process
+                // it and do the appropriate action.
+                if (PROCESS_HARD_KEYS) {
+                    if (keyCode == KeyEvent.KEYCODE_SPACE
+                            && (event.getMetaState()&KeyEvent.META_ALT_ON) != 0) {
+                        // A silly example: in our input method, Alt+Space
+                        // is a shortcut for 'android' in lower case.
+                        InputConnection ic = getCurrentInputConnection();
+                        if (ic != null) {
+                            // First, tell the editor that it is no longer in the
+                            // shift state, since we are consuming this.
+                            ic.clearMetaKeyStates(KeyEvent.META_ALT_ON);
+                            keyDownUp(KeyEvent.KEYCODE_A);
+                            keyDownUp(KeyEvent.KEYCODE_N);
+                            keyDownUp(KeyEvent.KEYCODE_D);
+                            keyDownUp(KeyEvent.KEYCODE_R);
+                            keyDownUp(KeyEvent.KEYCODE_O);
+                            keyDownUp(KeyEvent.KEYCODE_I);
+                            keyDownUp(KeyEvent.KEYCODE_D);
+                            // And we consume this event.
+                            return true;
+                        }
+                    }
+                    if (mPredictionOn && translateKeyDown(keyCode, event)) {
+                        return true;
+                    }
+                }
+        }
+        
+        return super.onKeyDown(keyCode, event);
+    }
+
+    /**
+     * Use this to monitor key events being delivered to the application.
+     * We get first crack at them, and can either resume them or let them
+     * continue to the app.
+     */
+    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
+        // If we want to do transformations on text being entered with a hard
+        // keyboard, we need to process the up events to update the meta key
+        // state we are tracking.
+        if (PROCESS_HARD_KEYS) {
+            if (mPredictionOn) {
+                mMetaState = MetaKeyKeyListener.handleKeyUp(mMetaState,
+                        keyCode, event);
+            }
+        }
+        
+        return super.onKeyUp(keyCode, event);
+    }
+
+    /**
+     * Helper function to commit any text being composed in to the editor.
+     */
+    private void commitTyped(InputConnection inputConnection) {
+        if (mComposing.length() > 0) {
+            inputConnection.commitText(mComposing, mComposing.length());
+            mComposing.setLength(0);
+            updateCandidates();
+        }
+    }
+
+    /**
+     * Helper to update the shift state of our keyboard based on the initial
+     * editor state.
+     */
+    private void updateShiftKeyState(EditorInfo attr) {
+        if (attr != null 
+                && mInputView != null && mQwertyKeyboard == mInputView.getKeyboard()) {
+            int caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
+            mInputView.setShifted(mCapsLock || caps != 0);
+        }
+    }
+    
+    /**
+     * Helper to determine if a given character code is alphabetic.
+     */
+    private boolean isAlphabet(int code) {
+        if (Character.isLetter(code)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Helper to send a key down / key up pair to the current editor.
+     */
+    private void keyDownUp(int keyEventCode) {
+        getCurrentInputConnection().sendKeyEvent(
+                new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
+        getCurrentInputConnection().sendKeyEvent(
+                new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
+    }
+    
+    /**
+     * Helper to send a character to the editor as raw key events.
+     */
+    private void sendKey(int keyCode) {
+        switch (keyCode) {
+            case '\n':
+                keyDownUp(KeyEvent.KEYCODE_ENTER);
+                break;
+            default:
+                if (keyCode >= '0' && keyCode <= '9') {
+                    keyDownUp(keyCode - '0' + KeyEvent.KEYCODE_0);
+                } else {
+                    getCurrentInputConnection().commitText(String.valueOf((char) keyCode), 1);
+                }
+                break;
+        }
+    }
+
+    // Implementation of KeyboardViewListener
+
+    public void onKey(int primaryCode, int[] keyCodes) {
+        if (isWordSeparator(primaryCode)) {
+            // Handle separator
+            if (mComposing.length() > 0) {
+                commitTyped(getCurrentInputConnection());
+            }
+            sendKey(primaryCode);
+            updateShiftKeyState(getCurrentInputEditorInfo());
+        } else if (primaryCode == Keyboard.KEYCODE_DELETE) {
+            handleBackspace();
+        } else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
+            handleShift();
+        } else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
+            handleClose();
+            return;
+        } else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) {
+            // Show a menu or somethin'
+        } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
+                && mInputView != null) {
+            Keyboard current = mInputView.getKeyboard();
+            if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) {
+                current = mQwertyKeyboard;
+            } else {
+                current = mSymbolsKeyboard;
+            }
+            mInputView.setKeyboard(current);
+            if (current == mSymbolsKeyboard) {
+                current.setShifted(false);
+            }
+        } else {
+            handleCharacter(primaryCode, keyCodes);
+        }
+    }
+
+    public void onText(CharSequence text) {
+        InputConnection ic = getCurrentInputConnection();
+        if (ic == null) return;
+        ic.beginBatchEdit();
+        if (mComposing.length() > 0) {
+            commitTyped(ic);
+        }
+        ic.commitText(text, 0);
+        ic.endBatchEdit();
+        updateShiftKeyState(getCurrentInputEditorInfo());
+    }
+
+    /**
+     * Update the list of available candidates from the current composing
+     * text.  This will need to be filled in by however you are determining
+     * candidates.
+     */
+    private void updateCandidates() {
+        if (!mCompletionOn) {
+            if (mComposing.length() > 0) {
+                ArrayList<String> list = new ArrayList<String>();
+                list.add(mComposing.toString());
+                setSuggestions(list, true, true);
+            } else {
+                setSuggestions(null, false, false);
+            }
+        }
+    }
+    
+    public void setSuggestions(List<String> suggestions, boolean completions,
+            boolean typedWordValid) {
+        if (suggestions != null && suggestions.size() > 0) {
+            setCandidatesViewShown(true);
+        } else if (isFullscreenMode()) {
+            setCandidatesViewShown(true);
+        }
+        if (mCandidateView != null) {
+            mCandidateView.setSuggestions(suggestions, completions, typedWordValid);
+        }
+    }
+    
+    private void handleBackspace() {
+        final int length = mComposing.length();
+        if (length > 1) {
+            mComposing.delete(length - 1, length);
+            getCurrentInputConnection().setComposingText(mComposing, mComposing.length());
+            updateCandidates();
+        } else if (length > 0) {
+            mComposing.setLength(0);
+            getCurrentInputConnection().commitText("", 0);
+            updateCandidates();
+        } else {
+            keyDownUp(KeyEvent.KEYCODE_DEL);
+        }
+        updateShiftKeyState(getCurrentInputEditorInfo());
+    }
+
+    private void handleShift() {
+        if (mInputView == null) {
+            return;
+        }
+        
+        Keyboard currentKeyboard = mInputView.getKeyboard();
+        if (mQwertyKeyboard == currentKeyboard) {
+            // Alphabet keyboard
+            checkToggleCapsLock();
+            mInputView.setShifted(mCapsLock || !mInputView.isShifted());
+        } else if (currentKeyboard == mSymbolsKeyboard) {
+            mSymbolsKeyboard.setShifted(true);
+            mInputView.setKeyboard(mSymbolsShiftedKeyboard);
+            mSymbolsShiftedKeyboard.setShifted(true);
+        } else if (currentKeyboard == mSymbolsShiftedKeyboard) {
+            mSymbolsShiftedKeyboard.setShifted(false);
+            mInputView.setKeyboard(mSymbolsKeyboard);
+            mSymbolsKeyboard.setShifted(false);
+        }
+    }
+    
+    private void handleCharacter(int primaryCode, int[] keyCodes) {
+        if (isInputViewShown()) {
+            if (mInputView.isShifted()) {
+                primaryCode = Character.toUpperCase(primaryCode);
+            }
+        }
+        if (isAlphabet(primaryCode) && mPredictionOn) {
+            mComposing.append((char) primaryCode);
+            getCurrentInputConnection().setComposingText(mComposing, mComposing.length());
+            updateShiftKeyState(getCurrentInputEditorInfo());
+            updateCandidates();
+        } else {
+            getCurrentInputConnection().commitText(
+                    String.valueOf((char) primaryCode), 1);
+        }
+    }
+
+    private void handleClose() {
+        commitTyped(getCurrentInputConnection());
+        dismissSoftInput(0);
+        mInputView.closing();
+    }
+
+    private void checkToggleCapsLock() {
+        long now = System.currentTimeMillis();
+        if (mLastShiftTime + 800 > now) {
+            mCapsLock = !mCapsLock;
+            mLastShiftTime = 0;
+        } else {
+            mLastShiftTime = now;
+        }
+    }
+    
+    private String getWordSeparators() {
+        return mWordSeparators;
+    }
+    
+    public boolean isWordSeparator(int code) {
+        String separators = getWordSeparators();
+        return separators.contains(String.valueOf((char)code));
+    }
+
+    public void pickDefaultCandidate() {
+        pickSuggestionManually(0);
+    }
+    
+    public void pickSuggestionManually(int index) {
+        if (mCompletionOn && mCompletions != null && index >= 0
+                && index < mCompletions.length) {
+            CompletionInfo ci = mCompletions[index];
+            getCurrentInputConnection().commitCompletion(ci);
+            if (mCandidateView != null) {
+                mCandidateView.clear();
+            }
+            updateShiftKeyState(getCurrentInputEditorInfo());
+        } else if (mComposing.length() > 0) {
+            // If we were generating candidate suggestions for the current
+            // text, we would commit one of them here.  But for this sample,
+            // we will just commit the current text.
+            commitTyped(getCurrentInputConnection());
+        }
+    }
+    
+    public void swipeRight() {
+        if (mCompletionOn) {
+            pickDefaultCandidate();
+        }
+    }
+    
+    public void swipeLeft() {
+        handleBackspace();
+    }
+
+    public void swipeDown() {
+        handleClose();
+    }
+
+    public void swipeUp() {
+    }
+    
+    public void onPress(int primaryCode) {
+    }
+    
+    public void onRelease(int primaryCode) {
+    }
+}