Merge "Revert "Build /system/bin/asan/app_process.""
diff --git a/api/current.txt b/api/current.txt
index eba8a2c..95007b5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -596,7 +596,7 @@
     field public static final int layerType = 16843604; // 0x1010354
     field public static final int layout = 16842994; // 0x10100f2
     field public static final int layoutAnimation = 16842988; // 0x10100ec
-    field public static final int layoutDirection = 16843689; // 0x10103a9
+    field public static final int layoutDirection = 16843690; // 0x10103aa
     field public static final int layout_above = 16843140; // 0x1010184
     field public static final int layout_alignBaseline = 16843142; // 0x1010186
     field public static final int layout_alignBottom = 16843146; // 0x101018a
@@ -618,10 +618,10 @@
     field public static final int layout_height = 16842997; // 0x10100f5
     field public static final int layout_margin = 16842998; // 0x10100f6
     field public static final int layout_marginBottom = 16843002; // 0x10100fa
-    field public static final int layout_marginEnd = 16843693; // 0x10103ad
+    field public static final int layout_marginEnd = 16843694; // 0x10103ae
     field public static final int layout_marginLeft = 16842999; // 0x10100f7
     field public static final int layout_marginRight = 16843001; // 0x10100f9
-    field public static final int layout_marginStart = 16843692; // 0x10103ac
+    field public static final int layout_marginStart = 16843693; // 0x10103ad
     field public static final int layout_marginTop = 16843000; // 0x10100f8
     field public static final int layout_row = 16843643; // 0x101037b
     field public static final int layout_rowSpan = 16843644; // 0x101037c
@@ -717,10 +717,10 @@
     field public static final int packageNames = 16843649; // 0x1010381
     field public static final int padding = 16842965; // 0x10100d5
     field public static final int paddingBottom = 16842969; // 0x10100d9
-    field public static final int paddingEnd = 16843691; // 0x10103ab
+    field public static final int paddingEnd = 16843692; // 0x10103ac
     field public static final int paddingLeft = 16842966; // 0x10100d6
     field public static final int paddingRight = 16842968; // 0x10100d8
-    field public static final int paddingStart = 16843690; // 0x10103aa
+    field public static final int paddingStart = 16843691; // 0x10103ab
     field public static final int paddingTop = 16842967; // 0x10100d7
     field public static final int panelBackground = 16842846; // 0x101005e
     field public static final int panelColorBackground = 16842849; // 0x1010061
@@ -931,6 +931,7 @@
     field public static final int summaryColumn = 16843426; // 0x10102a2
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
+    field public static final int supportsRtl = 16843688; // 0x10103a8
     field public static final int supportsUploading = 16843419; // 0x101029b
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
@@ -1000,7 +1001,7 @@
     field public static final int textColorTertiary = 16843282; // 0x1010212
     field public static final int textColorTertiaryInverse = 16843283; // 0x1010213
     field public static final int textCursorDrawable = 16843618; // 0x1010362
-    field public static final int textDirection = 16843688; // 0x10103a8
+    field public static final int textDirection = 16843689; // 0x10103a9
     field public static final int textEditNoPasteWindowLayout = 16843541; // 0x1010315
     field public static final int textEditPasteWindowLayout = 16843540; // 0x1010314
     field public static final int textEditSideNoPasteWindowLayout = 16843615; // 0x101035f
@@ -6131,6 +6132,7 @@
     field public static final int FLAG_STOPPED = 2097152; // 0x200000
     field public static final int FLAG_SUPPORTS_LARGE_SCREENS = 2048; // 0x800
     field public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1024; // 0x400
+    field public static final int FLAG_SUPPORTS_RTL = 4194304; // 0x400000
     field public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 8192; // 0x2000
     field public static final int FLAG_SUPPORTS_SMALL_SCREENS = 512; // 0x200
     field public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 524288; // 0x80000
@@ -23371,6 +23373,7 @@
     method public boolean hasFocus();
     method public boolean hasFocusable();
     method public boolean hasOnClickListeners();
+    method public boolean hasOverlappingRendering();
     method public boolean hasTransientState();
     method public boolean hasWindowFocus();
     method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
@@ -24102,9 +24105,11 @@
     ctor public ViewStub(android.content.Context, android.util.AttributeSet);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet, int);
     method public int getInflatedId();
+    method public android.view.LayoutInflater getLayoutInflater();
     method public int getLayoutResource();
     method public android.view.View inflate();
     method public void setInflatedId(int);
+    method public void setLayoutInflater(android.view.LayoutInflater);
     method public void setLayoutResource(int);
     method public void setOnInflateListener(android.view.ViewStub.OnInflateListener);
   }
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 9ebbe03..ddd7f7c 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -37,6 +37,14 @@
  * etc. Such a service can optionally request the capability for querying the content
  * of the active window. Development of an accessibility service requires extending this
  * class and implementing its abstract methods.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating AccessibilityServices, read the
+ * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+ * developer guide.</p>
+ * </div>
+ *
  * <h3>Lifecycle</h3>
  * <p>
  * The lifecycle of an accessibility service is managed exclusively by the system and
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index b55fda4..8e53431 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -42,6 +42,13 @@
  * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
  * according to the information encapsulated in this class.
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating AccessibilityServices, read the
+ * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+ * developer guide.</p>
+ * </div>
+ *
  * @see AccessibilityService
  * @see android.view.accessibility.AccessibilityEvent
  * @see android.view.accessibility.AccessibilityManager
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index bf8fde0..c62e5cf 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -92,8 +92,7 @@
         mCallBack = callBack;
 
         Context themeContext = getContext();
-        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_set), this);
-        setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel), (OnClickListener) null);
+        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
         setIcon(0);
         setTitle(R.string.date_picker_dialog_title);
 
@@ -106,11 +105,7 @@
     }
 
     public void onClick(DialogInterface dialog, int which) {
-        if (mCallBack != null) {
-            mDatePicker.clearFocus();
-            mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
-                    mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
-        }
+        tryNotifyDateSet();
     }
 
     public void onDateChanged(DatePicker view, int year,
@@ -138,6 +133,20 @@
         mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
     }
 
+    private void tryNotifyDateSet() {
+        if (mCallBack != null) {
+            mDatePicker.clearFocus();
+            mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
+                    mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        tryNotifyDateSet();
+        super.onStop();
+    }
+
     @Override
     public Bundle onSaveInstanceState() {
         Bundle state = super.onSaveInstanceState();
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 353b415..d773bc8 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -96,9 +96,7 @@
         setTitle(R.string.time_picker_dialog_title);
 
         Context themeContext = getContext();
-        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_set), this);
-        setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel),
-                (OnClickListener) null);
+        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
 
         LayoutInflater inflater =
                 (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -114,11 +112,7 @@
     }
 
     public void onClick(DialogInterface dialog, int which) {
-        if (mCallback != null) {
-            mTimePicker.clearFocus();
-            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
-                    mTimePicker.getCurrentMinute());
-        }
+        tryNotifyTimeSet();
     }
 
     public void updateTime(int hourOfDay, int minutOfHour) {
@@ -130,6 +124,20 @@
         /* do nothing */
     }
 
+    private void tryNotifyTimeSet() {
+        if (mCallback != null) {
+            mTimePicker.clearFocus();
+            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+                    mTimePicker.getCurrentMinute());
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        tryNotifyTimeSet();
+        super.onStop();
+    }
+
     @Override
     public Bundle onSaveInstanceState() {
         Bundle state = super.onSaveInstanceState();
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 65a8750..cbabc7c 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -291,6 +291,17 @@
     public static final int FLAG_STOPPED = 1<<21;
 
     /**
+     * Value for {@link #flags}: true  when the application is willing to support
+     * RTL (right to left). All activities will inherit this value.
+     *
+     * Set from the {@link android.R.attr#supportsRtl} attribute in the
+     * activity's manifest.
+     *
+     * Default value is false (no support for RTL).
+     */
+    public static final int FLAG_SUPPORTS_RTL = 1<<22;
+
+    /**
      * Value for {@link #flags}: Set to true if the application has been
      * installed using the forward lock option.
      *
@@ -466,8 +477,17 @@
         if (uiOptions != 0) {
             pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
         }
+        pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false"));
         super.dumpBack(pw, prefix);
     }
+
+    /**
+     * @return true if "supportsRtl" has been set to true in the AndroidManifest
+     * @hide
+     */
+    public boolean hasRtlSupport() {
+        return (flags & FLAG_SUPPORTS_RTL) == FLAG_SUPPORTS_RTL;
+    }
     
     public static class DisplayNameComparator
             implements Comparator<ApplicationInfo> {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index eb8536f..a79b86a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1761,6 +1761,12 @@
             ai.flags |= ApplicationInfo.FLAG_LARGE_HEAP;
         }
 
+        if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestApplication_supportsRtl,
+                false /* default is no RTL support*/)) {
+            ai.flags |= ApplicationInfo.FLAG_SUPPORTS_RTL;
+        }
+
         String str;
         str = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 74a376d..8df4339 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -497,27 +497,30 @@
      * @see #onCreateView(ViewGroup)
      */
     protected void onBindView(View view) {
-        TextView textView = (TextView) view.findViewById(com.android.internal.R.id.title); 
-        if (textView != null) {
-            textView.setText(getTitle());
-        }
-        
-        textView = (TextView) view.findViewById(com.android.internal.R.id.summary);
-        if (textView != null) {
-            final CharSequence summary = getSummary();
-            if (!TextUtils.isEmpty(summary)) {
-                if (textView.getVisibility() != View.VISIBLE) {
-                    textView.setVisibility(View.VISIBLE);
-                }
-                
-                textView.setText(getSummary());
+        final TextView titleView = (TextView) view.findViewById(
+                com.android.internal.R.id.title);
+        if (titleView != null) {
+            final CharSequence title = getTitle();
+            if (!TextUtils.isEmpty(title)) {
+                titleView.setText(title);
+                titleView.setVisibility(View.VISIBLE);
             } else {
-                if (textView.getVisibility() != View.GONE) {
-                    textView.setVisibility(View.GONE);
-                }
+                titleView.setVisibility(View.GONE);
             }
         }
-        
+
+        final TextView summaryView = (TextView) view.findViewById(
+                com.android.internal.R.id.summary);
+        if (summaryView != null) {
+            final CharSequence summary = getSummary();
+            if (!TextUtils.isEmpty(summary)) {
+                summaryView.setText(summary);
+                summaryView.setVisibility(View.VISIBLE);
+            } else {
+                summaryView.setVisibility(View.GONE);
+            }
+        }
+
         ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
         if (imageView != null) {
             if (mIconResId != 0 || mIcon != null) {
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 33631b7..fba73fbd 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -149,6 +149,15 @@
     public abstract void setAlpha(float alpha);
 
     /**
+     * Sets whether the DisplayList renders content which overlaps. Non-overlapping rendering
+     * can use a fast path for alpha that avoids rendering to an offscreen buffer.
+     *
+     * @param hasOverlappingRendering
+     * @see android.view.View#hasOverlappingRendering()
+     */
+    public abstract void setHasOverlappingRendering(boolean hasOverlappingRendering);
+
+    /**
      * Sets the translationX value for the DisplayList
      *
      * @param translationX The translationX value of the DisplayList
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index bc3bce0..f3618eb 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -147,6 +147,15 @@
     }
 
     @Override
+    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
+        try {
+            nSetHasOverlappingRendering(getNativeDisplayList(), hasOverlappingRendering);
+        } catch (IllegalStateException e) {
+            // invalid DisplayList okay: we'll set current values the next time we render to it
+        }
+    }
+
+    @Override
     public void setTranslationX(float translationX) {
         try {
             nSetTranslationX(getNativeDisplayList(), translationX);
@@ -335,6 +344,8 @@
     private static native void nSetClipChildren(int displayList, boolean clipChildren);
     private static native void nSetApplicationScale(int displayList, float scale);
     private static native void nSetAlpha(int displayList, float alpha);
+    private static native void nSetHasOverlappingRendering(int displayList,
+            boolean hasOverlappingRendering);
     private static native void nSetTranslationX(int displayList, float translationX);
     private static native void nSetTranslationY(int displayList, float translationY);
     private static native void nSetRotation(int displayList, float rotation);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index b100a0c..9ef2621 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -134,7 +134,7 @@
     /**
      * Number of frames to profile.
      */
-    private static final int PROFILE_MAX_FRAMES = 64;
+    private static final int PROFILE_MAX_FRAMES = 120;
 
     /**
      * Number of floats per profiled frame.
@@ -1046,10 +1046,6 @@
                                 Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- getDisplayList() took " +
                                         total + "ms");
                             }
-                            if (View.USE_DISPLAY_LIST_PROPERTIES) {
-                                Log.d("DLProperties", "getDisplayList():\t" +
-                                        mProfileData[mProfileCurrentFrame]);
-                            }
                         }
 
                         if (displayList != null) {
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 3c0ee12..26a5b26 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -583,7 +583,14 @@
 
             Object[] args = mConstructorArgs;
             args[1] = attrs;
-            return constructor.newInstance(args);
+
+            final View view = constructor.newInstance(args);
+            if (view instanceof ViewStub) {
+                // always use ourselves when inflating ViewStub later
+                final ViewStub viewStub = (ViewStub) view;
+                viewStub.setLayoutInflater(this);
+            }
+            return view;
 
         } catch (NoSuchMethodException e) {
             InflateException ie = new InflateException(attrs.getPositionDescription()
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 18e1697..c40a7d5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2830,19 +2830,6 @@
     private boolean mSendingHoverAccessibilityEvents;
 
     /**
-     * Delegate for injecting accessiblity functionality.
-     */
-    AccessibilityDelegate mAccessibilityDelegate;
-
-    /**
-     * Consistency verifier for debugging purposes.
-     * @hide
-     */
-    protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
-            InputEventConsistencyVerifier.isInstrumentationEnabled() ?
-                    new InputEventConsistencyVerifier(this, 0) : null;
-
-    /**
      * Simple constructor to use when creating a view from code.
      *
      * @param context The Context the view is running in, through which it can
@@ -2863,6 +2850,19 @@
     }
 
     /**
+     * Delegate for injecting accessiblity functionality.
+     */
+    AccessibilityDelegate mAccessibilityDelegate;
+
+    /**
+     * Consistency verifier for debugging purposes.
+     * @hide
+     */
+    protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
+            InputEventConsistencyVerifier.isInstrumentationEnabled() ?
+                    new InputEventConsistencyVerifier(this, 0) : null;
+
+    /**
      * Constructor that is called when inflating a view from XML. This is called
      * when a view is being constructed from an XML file, supplying attributes
      * that were specified in the XML file. This version uses a default style of
@@ -7855,6 +7855,23 @@
     }
 
     /**
+     * Returns whether this View has content which overlaps. This function, intended to be
+     * overridden by specific View types, is an optimization when alpha is set on a view. If
+     * rendering overlaps in a view with alpha < 1, that view is drawn to an offscreen buffer
+     * and then composited it into place, which can be expensive. If the view has no overlapping
+     * rendering, the view can draw each primitive with the appropriate alpha value directly.
+     * An example of overlapping rendering is a TextView with a background image, such as a
+     * Button. An example of non-overlapping rendering is a TextView with no background, or
+     * an ImageView with only the foreground image. The default implementation returns true;
+     * subclasses should override if they have cases which can be optimized.
+     *
+     * @return true if the content in this view might overlap, false otherwise.
+     */
+    public boolean hasOverlappingRendering() {
+        return true;
+    }
+
+    /**
      * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
      * completely transparent and 1 means the view is completely opaque.</p>
      *
@@ -9998,6 +10015,13 @@
     }
 
     /**
+     * Return true if the application tag in the AndroidManifest has set "supportRtl" to true
+     */
+    private boolean hasRtlSupport() {
+        return mContext.getApplicationInfo().hasRtlSupport();
+    }
+
+    /**
      * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
      * that the parent directionality can and will be resolved before its children.
      * Will call {@link View#onResolvedLayoutDirectionChanged} when resolution is done.
@@ -10006,30 +10030,32 @@
         // Clear any previous layout direction resolution
         mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK;
 
-        // Set resolved depending on layout direction
-        switch (getLayoutDirection()) {
-            case LAYOUT_DIRECTION_INHERIT:
-                // If this is root view, no need to look at parent's layout dir.
-                if (canResolveLayoutDirection()) {
-                    ViewGroup viewGroup = ((ViewGroup) mParent);
+        if (hasRtlSupport()) {
+            // Set resolved depending on layout direction
+            switch (getLayoutDirection()) {
+                case LAYOUT_DIRECTION_INHERIT:
+                    // If this is root view, no need to look at parent's layout dir.
+                    if (canResolveLayoutDirection()) {
+                        ViewGroup viewGroup = ((ViewGroup) mParent);
 
-                    if (viewGroup.getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                        if (viewGroup.getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                            mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+                        }
+                    } else {
+                        // Nothing to do, LTR by default
+                    }
+                    break;
+                case LAYOUT_DIRECTION_RTL:
+                    mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+                    break;
+                case LAYOUT_DIRECTION_LOCALE:
+                    if(isLayoutDirectionRtl(Locale.getDefault())) {
                         mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
                     }
-                } else {
+                    break;
+                default:
                     // Nothing to do, LTR by default
-                }
-                break;
-            case LAYOUT_DIRECTION_RTL:
-                mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
-                break;
-            case LAYOUT_DIRECTION_LOCALE:
-                if(isLayoutDirectionRtl(Locale.getDefault())) {
-                    mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
-                }
-                break;
-            default:
-                // Nothing to do, LTR by default
+            }
         }
 
         // Set to resolved
@@ -11525,6 +11551,7 @@
     void setDisplayListProperties(DisplayList displayList) {
         if (USE_DISPLAY_LIST_PROPERTIES && displayList != null) {
             displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
+            displayList.setHasOverlappingRendering(hasOverlappingRendering());
             if (mParent instanceof ViewGroup) {
                 displayList.setClipChildren(
                         (((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
@@ -14809,44 +14836,49 @@
         // Reset any previous text direction resolution
         mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK);
 
-        // Set resolved text direction flag depending on text direction flag
-        final int textDirection = getTextDirection();
-        switch(textDirection) {
-            case TEXT_DIRECTION_INHERIT:
-                if (canResolveTextDirection()) {
-                    ViewGroup viewGroup = ((ViewGroup) mParent);
+        if (hasRtlSupport()) {
+            // Set resolved text direction flag depending on text direction flag
+            final int textDirection = getTextDirection();
+            switch(textDirection) {
+                case TEXT_DIRECTION_INHERIT:
+                    if (canResolveTextDirection()) {
+                        ViewGroup viewGroup = ((ViewGroup) mParent);
 
-                    // Set current resolved direction to the same value as the parent's one
-                    final int parentResolvedDirection = viewGroup.getResolvedTextDirection();
-                    switch (parentResolvedDirection) {
-                        case TEXT_DIRECTION_FIRST_STRONG:
-                        case TEXT_DIRECTION_ANY_RTL:
-                        case TEXT_DIRECTION_LTR:
-                        case TEXT_DIRECTION_RTL:
-                        case TEXT_DIRECTION_LOCALE:
-                            mPrivateFlags2 |=
-                                    (parentResolvedDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
-                            break;
-                        default:
-                            // Default resolved direction is "first strong" heuristic
-                            mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+                        // Set current resolved direction to the same value as the parent's one
+                        final int parentResolvedDirection = viewGroup.getResolvedTextDirection();
+                        switch (parentResolvedDirection) {
+                            case TEXT_DIRECTION_FIRST_STRONG:
+                            case TEXT_DIRECTION_ANY_RTL:
+                            case TEXT_DIRECTION_LTR:
+                            case TEXT_DIRECTION_RTL:
+                            case TEXT_DIRECTION_LOCALE:
+                                mPrivateFlags2 |=
+                                        (parentResolvedDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+                                break;
+                            default:
+                                // Default resolved direction is "first strong" heuristic
+                                mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+                        }
+                    } else {
+                        // We cannot do the resolution if there is no parent, so use the default one
+                        mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
                     }
-                } else {
-                    // We cannot do the resolution if there is no parent, so use the default one
+                    break;
+                case TEXT_DIRECTION_FIRST_STRONG:
+                case TEXT_DIRECTION_ANY_RTL:
+                case TEXT_DIRECTION_LTR:
+                case TEXT_DIRECTION_RTL:
+                case TEXT_DIRECTION_LOCALE:
+                    // Resolved direction is the same as text direction
+                    mPrivateFlags2 |= (textDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+                    break;
+                default:
+                    // Default resolved direction is "first strong" heuristic
                     mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
-                }
-                break;
-            case TEXT_DIRECTION_FIRST_STRONG:
-            case TEXT_DIRECTION_ANY_RTL:
-            case TEXT_DIRECTION_LTR:
-            case TEXT_DIRECTION_RTL:
-            case TEXT_DIRECTION_LOCALE:
-                // Resolved direction is the same as text direction
-                mPrivateFlags2 |= (textDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
-                break;
-            default:
-                // Default resolved direction is "first strong" heuristic
-                mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+            }
+        } else {
+            // Default resolved direction is "first strong" heuristic
+            mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
         }
 
         // Set to resolved
@@ -15901,6 +15933,12 @@
      * classes i.e. classes in package android.view, that would like their
      * applications to be backwards compatible.
      * </p>
+     * <div class="special reference">
+     * <h3>Developer Guides</h3>
+     * <p>For more information about making applications accessible, read the
+     * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+     * developer guide.</p>
+     * </div>
      * <p>
      * A scenario in which a developer would like to use an accessibility delegate
      * is overriding a method introduced in a later API version then the minimal API
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 20183ee..b9924c7 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -31,14 +31,14 @@
 public class ViewConfiguration {
     /**
      * Expected bit depth of the display panel.
-     * 
+     *
      * @hide
      */
     public static final float PANEL_BIT_DEPTH = 24;
 
     /**
      * Minimum alpha required for a view to draw.
-     * 
+     *
      * @hide
      */
     public static final float ALPHA_THRESHOLD = 0.5f / PANEL_BIT_DEPTH;
@@ -72,8 +72,8 @@
      * Defines the duration in milliseconds of the pressed state in child
      * components.
      */
-    private static final int PRESSED_STATE_DURATION = 125;
-    
+    private static final int PRESSED_STATE_DURATION = 64;
+
     /**
      * Defines the default duration in milliseconds before a press turns into
      * a long press
@@ -91,18 +91,18 @@
      * lock screen, etc).
      */
     private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500;
-    
+
     /**
-     * Defines the duration in milliseconds we will wait to see if a touch event 
+     * Defines the duration in milliseconds we will wait to see if a touch event
      * is a tap or a scroll. If the user does not move within this interval, it is
-     * considered to be a tap. 
+     * considered to be a tap.
      */
     private static final int TAP_TIMEOUT = 180;
-    
+
     /**
-     * Defines the duration in milliseconds we will wait to see if a touch event 
+     * Defines the duration in milliseconds we will wait to see if a touch event
      * is a jump tap. If the user does not complete the jump tap within this interval, it is
-     * considered to be a tap. 
+     * considered to be a tap.
      */
     private static final int JUMP_TAP_TIMEOUT = 500;
 
@@ -128,7 +128,7 @@
     private static final int HOVER_TAP_SLOP = 20;
 
     /**
-     * Defines the duration in milliseconds we want to display zoom controls in response 
+     * Defines the duration in milliseconds we want to display zoom controls in response
      * to a user panning within an application.
      */
     private static final int ZOOM_CONTROLS_TIMEOUT = 3000;
@@ -137,7 +137,7 @@
      * Inset in dips to look for touchable content when the user touches the edge of the screen
      */
     private static final int EDGE_SLOP = 12;
-    
+
     /**
      * Distance a touch can wander before we think the user is scrolling in dips.
      * Note that this value defined here is only used as a fallback by legacy/misbehaving
@@ -150,7 +150,7 @@
      * the characteristics of the touch panel and firmware.
      */
     private static final int TOUCH_SLOP = 8;
-    
+
     /**
      * Distance the first touch can wander before we stop considering this event a double tap
      * (in dips)
@@ -170,12 +170,12 @@
      * config_viewConfigurationTouchSlop * 2 when provided with a Context.
      */
     private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2;
-    
+
     /**
      * Distance in dips between the first touch and second touch to still be considered a double tap
      */
     private static final int DOUBLE_TAP_SLOP = 100;
-    
+
     /**
      * Distance in dips a touch needs to be outside of a window's bounds for it to
      * count as outside for purposes of dismissing the window.
@@ -186,7 +186,7 @@
      * Minimum velocity to initiate a fling, as measured in dips per second
      */
     private static final int MINIMUM_FLING_VELOCITY = 50;
-    
+
     /**
      * Maximum velocity to initiate a fling, as measured in dips per second
      */
@@ -281,7 +281,7 @@
      *
      * @param context The application context used to initialize this view configuration.
      *
-     * @see #get(android.content.Context) 
+     * @see #get(android.content.Context)
      * @see android.util.DisplayMetrics
      */
     private ViewConfiguration(Context context) {
@@ -383,7 +383,7 @@
     public static int getScrollDefaultDelay() {
         return SCROLL_BAR_DEFAULT_DELAY;
     }
-    
+
     /**
      * @return the length of the fading edges in dips
      *
@@ -435,7 +435,7 @@
     /**
      * @return the duration in milliseconds we will wait to see if a touch event
      * is a tap or a scroll. If the user does not move within this interval, it is
-     * considered to be a tap. 
+     * considered to be a tap.
      */
     public static int getTapTimeout() {
         return TAP_TIMEOUT;
@@ -444,12 +444,12 @@
     /**
      * @return the duration in milliseconds we will wait to see if a touch event
      * is a jump tap. If the user does not move within this interval, it is
-     * considered to be a tap. 
+     * considered to be a tap.
      */
     public static int getJumpTapTimeout() {
         return JUMP_TAP_TIMEOUT;
     }
-    
+
     /**
      * @return the duration in milliseconds between the first tap's up event and
      * the second tap's down event for an interaction to be considered a
@@ -514,7 +514,7 @@
     public int getScaledTouchSlop() {
         return mTouchSlop;
     }
-    
+
     /**
      * @return Distance in pixels the first touch can wander before we do not consider this a
      * potential double tap event
@@ -543,7 +543,7 @@
     public static int getDoubleTapSlop() {
         return DOUBLE_TAP_SLOP;
     }
-    
+
     /**
      * @return Distance in pixels between the first touch and second touch to still be
      *         considered a double tap
@@ -595,7 +595,7 @@
     public int getScaledWindowTouchSlop() {
         return mWindowTouchSlop;
     }
-    
+
     /**
      * @return Minimum velocity to initiate a fling, as measured in dips per second.
      *
@@ -629,7 +629,7 @@
     public int getScaledMaximumFlingVelocity() {
         return mMaximumFlingVelocity;
     }
-    
+
     /**
      * The maximum drawing cache size expressed in bytes.
      *
@@ -671,7 +671,7 @@
     /**
      * The amount of time that the zoom controls should be
      * displayed on the screen expressed in milliseconds.
-     * 
+     *
      * @return the time the zoom controls should be visible expressed
      * in milliseconds.
      */
@@ -692,7 +692,7 @@
 
     /**
      * The amount of friction applied to scrolls and flings.
-     * 
+     *
      * @return A scalar dimensionless value representing the coefficient of
      *         friction.
      */
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 623b567..3626aba 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -834,40 +834,49 @@
      */
     private void setValue(int propertyConstant, float value) {
         final View.TransformationInfo info = mView.mTransformationInfo;
+        DisplayList displayList = View.USE_DISPLAY_LIST_PROPERTIES ? mView.mDisplayList : null;
         switch (propertyConstant) {
             case TRANSLATION_X:
                 info.mTranslationX = value;
+                if (displayList != null) displayList.setTranslationX(value);
                 break;
             case TRANSLATION_Y:
                 info.mTranslationY = value;
+                if (displayList != null) displayList.setTranslationY(value);
                 break;
             case ROTATION:
                 info.mRotation = value;
+                if (displayList != null) displayList.setRotation(value);
                 break;
             case ROTATION_X:
                 info.mRotationX = value;
+                if (displayList != null) displayList.setRotationX(value);
                 break;
             case ROTATION_Y:
                 info.mRotationY = value;
+                if (displayList != null) displayList.setRotationY(value);
                 break;
             case SCALE_X:
                 info.mScaleX = value;
+                if (displayList != null) displayList.setScaleX(value);
                 break;
             case SCALE_Y:
                 info.mScaleY = value;
+                if (displayList != null) displayList.setScaleY(value);
                 break;
             case X:
                 info.mTranslationX = value - mView.mLeft;
+                if (displayList != null) displayList.setTranslationX(value - mView.mLeft);
                 break;
             case Y:
                 info.mTranslationY = value - mView.mTop;
+                if (displayList != null) displayList.setTranslationY(value - mView.mTop);
                 break;
             case ALPHA:
                 info.mAlpha = value;
+                if (displayList != null) displayList.setAlpha(value);
                 break;
         }
-        // TODO: optimize to set only the properties that have changed
-        mView.setDisplayListProperties();
     }
 
     /**
diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java
index d5e9af4..69a26c2 100644
--- a/core/java/android/view/ViewStub.java
+++ b/core/java/android/view/ViewStub.java
@@ -20,6 +20,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
+import android.widget.RemoteViews.RemoteView;
 
 import com.android.internal.R;
 
@@ -66,12 +67,14 @@
  * @attr ref android.R.styleable#ViewStub_inflatedId
  * @attr ref android.R.styleable#ViewStub_layout
  */
+@RemoteView
 public final class ViewStub extends View {
     private int mLayoutResource = 0;
     private int mInflatedId;
 
     private WeakReference<View> mInflatedViewRef;
 
+    private LayoutInflater mInflater;
     private OnInflateListener mInflateListener;
 
     public ViewStub(Context context) {
@@ -140,6 +143,7 @@
      * @see #getInflatedId()
      * @attr ref android.R.styleable#ViewStub_inflatedId
      */
+    @android.view.RemotableViewMethod
     public void setInflatedId(int inflatedId) {
         mInflatedId = inflatedId;
     }
@@ -172,10 +176,26 @@
      * @see #inflate()
      * @attr ref android.R.styleable#ViewStub_layout
      */
+    @android.view.RemotableViewMethod
     public void setLayoutResource(int layoutResource) {
         mLayoutResource = layoutResource;
     }
 
+    /**
+     * Set {@link LayoutInflater} to use in {@link #inflate()}, or {@code null}
+     * to use the default.
+     */
+    public void setLayoutInflater(LayoutInflater inflater) {
+        mInflater = inflater;
+    }
+
+    /**
+     * Get current {@link LayoutInflater} used in {@link #inflate()}.
+     */
+    public LayoutInflater getLayoutInflater() {
+        return mInflater;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         setMeasuredDimension(0, 0);
@@ -199,6 +219,7 @@
      * @see #inflate() 
      */
     @Override
+    @android.view.RemotableViewMethod
     public void setVisibility(int visibility) {
         if (mInflatedViewRef != null) {
             View view = mInflatedViewRef.get();
@@ -228,7 +249,12 @@
         if (viewParent != null && viewParent instanceof ViewGroup) {
             if (mLayoutResource != 0) {
                 final ViewGroup parent = (ViewGroup) viewParent;
-                final LayoutInflater factory = LayoutInflater.from(mContext);
+                final LayoutInflater factory;
+                if (mInflater != null) {
+                    factory = mInflater;
+                } else {
+                    factory = LayoutInflater.from(mContext);
+                }
                 final View view = factory.inflate(mLayoutResource, parent,
                         false);
 
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 58844fc..0998c80 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -59,6 +59,12 @@
  * by this class. For each event type there is a corresponding constant defined
  * in this class. Follows a specification of the event types and their associated properties:
  * </p>
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating and processing AccessibilityEvents, read the
+ * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+ * developer guide.</p>
+ * </div>
  * <p>
  * <b>VIEW TYPES</b></br>
  * </p>
diff --git a/core/java/android/view/accessibility/AccessibilityEventSource.java b/core/java/android/view/accessibility/AccessibilityEventSource.java
index f11880b..525ba9e 100644
--- a/core/java/android/view/accessibility/AccessibilityEventSource.java
+++ b/core/java/android/view/accessibility/AccessibilityEventSource.java
@@ -18,6 +18,13 @@
 
 /**
  * This interface is implemented by classes source of {@link AccessibilityEvent}s.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about making applications accessible, read the
+ * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+ * developer guide.</p>
+ * </div>
  */
 public interface AccessibilityEventSource {
 
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 03c6211..f616dca 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -43,6 +43,12 @@
  * details about how to obtain a handle to window content as a tree of accessibility
  * node info as well as familiarizing with the security model.
  * </p>
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about making applications accessible, read the
+ * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+ * developer guide.</p>
+ * </div>
  *
  * @see android.accessibilityservice.AccessibilityService
  * @see AccessibilityEvent
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index bc6074f..d25b3db 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -41,6 +41,13 @@
  * event types. For detailed information please refer to {@link AccessibilityEvent}.
  * </p>
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating and processing AccessibilityRecords, read the
+ * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+ * developer guide.</p>
+ * </div>
+ *
  * @see AccessibilityEvent
  * @see AccessibilityManager
  * @see android.accessibilityservice.AccessibilityService
diff --git a/core/java/android/view/accessibility/package.html b/core/java/android/view/accessibility/package.html
index 4afafd3..c2da0ae 100644
--- a/core/java/android/view/accessibility/package.html
+++ b/core/java/android/view/accessibility/package.html
@@ -35,5 +35,12 @@
   changes etc. Parties interested in handling accessibility events implement and register an
   accessibility service which extends {@link android.accessibilityservice.AccessibilityService}.
 </p>
+<div class="special reference">
+<h3>Developer Guides</h3>
+<p>For more information about making applications accessible, read the
+<a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
+developer guide.</p>
+</div>
+
 </body>
 </html>
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 422b48d..9492e38 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1913,13 +1913,6 @@
     }
 
     @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        // Not using short-circuit OR: provider does suppress base-class call.
-        return mProvider.getViewDelegate().drawChild(canvas, child, drawingTime) |
-                super.drawChild(canvas, child, drawingTime);
-    }
-
-    @Override
     protected void onDraw(Canvas canvas) {
         mProvider.getViewDelegate().onDraw(canvas);
     }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 45c5fa0..4c118ac 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -2011,7 +2011,7 @@
         if (mWebView instanceof TitleBarDelegate) {
             return ((TitleBarDelegate) mWebView).getTitleHeight();
         }
-        return mTitleBar != null ? mTitleBar.getHeight() : 0;
+        return 0;
     }
 
     /**
@@ -2943,50 +2943,6 @@
     }
 
     /**
-     * A title bar which is embedded in this WebView, and scrolls along with it
-     * vertically, but not horizontally.
-     */
-    private View mTitleBar;
-
-    /**
-     * the title bar rendering gravity
-     */
-    private int mTitleGravity;
-
-    /**
-     * Add or remove a title bar to be embedded into the WebView, and scroll
-     * along with it vertically, while remaining in view horizontally. Pass
-     * null to remove the title bar from the WebView, and return to drawing
-     * the WebView normally without translating to account for the title bar.
-     */
-    public void setEmbeddedTitleBar(View v) {
-        if (mWebView instanceof TitleBarDelegate) {
-            ((TitleBarDelegate) mWebView).onSetEmbeddedTitleBar(v);
-        }
-        if (mTitleBar == v) return;
-        if (mTitleBar != null) {
-            mWebView.removeView(mTitleBar);
-        }
-        if (null != v) {
-            mWebView.addView(v, new AbsoluteLayout.LayoutParams(
-                    ViewGroup.LayoutParams.MATCH_PARENT,
-                    ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0));
-        }
-        mTitleBar = v;
-    }
-
-    /**
-     * Set where to render the embedded title bar
-     * NO_GRAVITY at the top of the page
-     * TOP        at the top of the screen
-     */
-    public void setTitleBarGravity(int gravity) {
-        mTitleGravity = gravity;
-        // force refresh
-        invalidate();
-    }
-
-    /**
      * Given a distance in view space, convert it to content space. Note: this
      * does not reflect translation, just scaling, so this should not be called
      * with coordinates, but should be called for dimensions like width or
@@ -4184,7 +4140,7 @@
         // animate the title bar off screen slowly enough that the user can see
         // it.
         if (cx == 0 && cy == 1 && getScrollX() == 0 && getScrollY() == 0
-                && mTitleBar != null) {
+                && getTitleHeight() > 0) {
             // FIXME: 100 should be defined somewhere as our max progress.
             if (getProgress() < 100) {
                 // Wait to scroll the title bar off screen until the page has
@@ -4401,24 +4357,6 @@
         }
     }
 
-    @Override
-    public boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        if (child == mTitleBar) {
-            // When drawing the title bar, move it horizontally to always show
-            // at the top of the WebView.
-            mTitleBar.offsetLeftAndRight(getScrollX() - mTitleBar.getLeft());
-            int newTop = 0;
-            if (mTitleGravity == Gravity.NO_GRAVITY) {
-                newTop = Math.min(0, getScrollY());
-            } else if (mTitleGravity == Gravity.TOP) {
-                newTop = getScrollY();
-            }
-            mTitleBar.setBottom(newTop + mTitleBar.getHeight());
-            mTitleBar.setTop(newTop);
-        }
-        return false;  // We never call invalidate(), so unconditionally returning false.
-    }
-
     private void drawContent(Canvas canvas) {
         if (mDrawHistory) {
             canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
@@ -4583,9 +4521,8 @@
                 .getUseWebViewBackgroundForOverscrollBackground()) {
             drawOverScrollBackground(canvas);
         }
-        if (mTitleBar != null) {
-            canvas.translate(0, getTitleHeight());
-        }
+
+        canvas.translate(0, getTitleHeight());
         drawContent(canvas);
         canvas.restoreToCount(saveCount);
 
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index f049198..74a215c 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -287,8 +287,6 @@
 
         public void onWindowVisibilityChanged(int visibility);
 
-        public boolean drawChild(Canvas canvas, View child, long drawingTime);
-
         public void onDraw(Canvas canvas);
 
         public void setLayoutParams(LayoutParams layoutParams);
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index b1a75e1..91e2e497 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -201,7 +201,7 @@
 
     @Override
     protected boolean onSetAlpha(int alpha) {
-        if (getBackground() == null) {
+        if (!USE_DISPLAY_LIST_PROPERTIES && getBackground() == null) {
             int scale = alpha + (alpha >> 7);
             if (mViewAlphaScale != scale) {
                 mViewAlphaScale = scale;
@@ -214,6 +214,15 @@
     }
 
     @Override
+    public boolean hasOverlappingRendering() {
+        if (!USE_DISPLAY_LIST_PROPERTIES) {
+            return super.hasOverlappingRendering();
+        } else {
+            return (getBackground() != null);
+        }
+    }
+
+    @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
         super.onPopulateAccessibilityEvent(event);
         CharSequence contentDescription = getContentDescription();
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 4e56cd6..d897a39 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -112,10 +112,10 @@
     private static final int SELECTOR_ADJUSTMENT_DURATION_MILLIS = 800;
 
     /**
-     * The duration of scrolling to the next/previous value while changing the
-     * current value by one, i.e. increment or decrement.
+     * The duration of scrolling to the next/previous value while snapping to
+     * a given position.
      */
-    private static final int CHANGE_CURRENT_BY_ONE_SCROLL_DURATION = 300;
+    private static final int SNAP_SCROLL_DURATION = 300;
 
     /**
      * The strength of fading in the top and bottom while drawing the selector.
@@ -140,7 +140,7 @@
     /**
      * Coefficient for adjusting touch scroll distance.
      */
-    private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.5f;
+    private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.0f;
 
     /**
      * The resource id for the default layout.
@@ -152,7 +152,7 @@
      */
     private static final char[] DIGIT_CHARACTERS = new char[] {
             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
-     };
+    };
 
     /**
      * Constant for unspecified size.
@@ -838,7 +838,13 @@
                     if (absDeltaMoveY > mMinFlingDistance) {
                         fling(initialVelocity);
                     } else {
-                        changeValueByOne(deltaMove < 0);
+                        final int normalizedDeltaMove =
+                            (int) (absDeltaMoveY / TOUCH_SCROLL_DECELERATION_COEFFICIENT);
+                        if (normalizedDeltaMove < mSelectorElementHeight) {
+                            snapToNextValue(deltaMove < 0);
+                        } else {
+                            snapToClosestValue();
+                        }
                     }
                     onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
                 } else {
@@ -1509,11 +1515,9 @@
             }
             mPreviousScrollerY = 0;
             if (increment) {
-                mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight,
-                        CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
+                mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight, SNAP_SCROLL_DURATION);
             } else {
-                mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight,
-                        CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
+                mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight, SNAP_SCROLL_DURATION);
             }
             invalidate();
         } else {
@@ -1902,6 +1906,42 @@
         return false;
     }
 
+    private void snapToNextValue(boolean increment) {
+        int deltaY = mCurrentScrollOffset - mInitialScrollOffset;
+        int amountToScroll = 0;
+        if (deltaY != 0) {
+            mPreviousScrollerY = 0;
+            if (deltaY > 0) {
+                if (increment) {
+                    amountToScroll = - deltaY;
+                } else {
+                    amountToScroll = mSelectorElementHeight - deltaY;
+                }
+            } else {
+                if (increment) {
+                    amountToScroll = - mSelectorElementHeight - deltaY;
+                } else {
+                    amountToScroll = - deltaY;
+                }
+            }
+            mFlingScroller.startScroll(0, 0, 0, amountToScroll, SNAP_SCROLL_DURATION);
+            invalidate();
+        }
+    }
+
+    private void snapToClosestValue() {
+        // adjust to the closest value
+        int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
+        if (deltaY != 0) {
+            mPreviousScrollerY = 0;
+            if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
+                deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
+            }
+            mFlingScroller.startScroll(0, 0, 0, deltaY, SNAP_SCROLL_DURATION);
+            invalidate();
+        }
+    }
+
     /**
      * Command for setting the input text selection.
      */
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2a81f08..d2a1755 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4268,7 +4268,8 @@
     protected boolean onSetAlpha(int alpha) {
         // Alpha is supported if and only if the drawing can be done in one pass.
         // TODO text with spans with a background color currently do not respect this alpha.
-        if (getBackground() == null) {
+        if (!USE_DISPLAY_LIST_PROPERTIES &&
+                (getBackground() != null || mText instanceof Spannable || hasSelection())) {
             if (mCurrentAlpha != alpha) {
                 mCurrentAlpha = alpha;
                 final Drawables dr = mDrawables;
@@ -4292,6 +4293,15 @@
         return false;
     }
 
+    @Override
+    public boolean hasOverlappingRendering() {
+        if (!USE_DISPLAY_LIST_PROPERTIES) {
+            return super.hasOverlappingRendering();
+        } else {
+            return (getBackground() != null || mText instanceof Spannable || hasSelection());
+        }
+    }
+
     /**
      * When a TextView is used to display a useful piece of information to the user (such as a
      * contact's address), it should be made selectable, so that the user can select and copy this
diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp
index 60fb6d4..b307a2f 100644
--- a/core/jni/android_view_GLES20DisplayList.cpp
+++ b/core/jni/android_view_GLES20DisplayList.cpp
@@ -65,6 +65,11 @@
     displayList->setAlpha(alpha);
 }
 
+static void android_view_GLES20DisplayList_setHasOverlappingRendering(JNIEnv* env,
+        jobject clazz, DisplayList* displayList, bool hasOverlappingRendering) {
+    displayList->setHasOverlappingRendering(hasOverlappingRendering);
+}
+
 static void android_view_GLES20DisplayList_setTranslationX(JNIEnv* env,
         jobject clazz, DisplayList* displayList, float tx) {
     displayList->setTranslationX(tx);
@@ -185,6 +190,8 @@
     { "nSetAnimationMatrix",   "(II)V",  (void*) android_view_GLES20DisplayList_setAnimationMatrix },
     { "nSetClipChildren",      "(IZ)V",  (void*) android_view_GLES20DisplayList_setClipChildren },
     { "nSetAlpha",             "(IF)V",  (void*) android_view_GLES20DisplayList_setAlpha },
+    { "nSetHasOverlappingRendering", "(IZ)V",
+            (void*) android_view_GLES20DisplayList_setHasOverlappingRendering },
     { "nSetTranslationX",      "(IF)V",  (void*) android_view_GLES20DisplayList_setTranslationX },
     { "nSetTranslationY",      "(IF)V",  (void*) android_view_GLES20DisplayList_setTranslationY },
     { "nSetRotation",          "(IF)V",  (void*) android_view_GLES20DisplayList_setRotation },
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
index fb62eb6..36d4a2a 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
@@ -98,7 +98,7 @@
                     android:textAppearance="?android:attr/textAppearanceMedium"
                     android:background="@null"
                     android:textColor="#ffffffff"
-                    android:imeOptions="flagForceAscii"
+                    android:imeOptions="flagForceAscii|actionDone"
                 />
 
                 <!-- This delete button is only visible for numeric PIN entry -->
diff --git a/core/res/res/layout/date_picker_holo.xml b/core/res/res/layout/date_picker_holo.xml
index 57b5614..122a61a 100644
--- a/core/res/res/layout/date_picker_holo.xml
+++ b/core/res/res/layout/date_picker_holo.xml
@@ -41,6 +41,8 @@
             android:id="@+id/month"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginTop="10dip"
+            android:layout_marginBottom="10dip"
             android:layout_marginLeft="16dip"
             android:layout_marginRight="16dip"
             android:focusable="true"
@@ -52,6 +54,8 @@
             android:id="@+id/day"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginTop="10dip"
+            android:layout_marginBottom="10dip"
             android:layout_marginLeft="16dip"
             android:layout_marginRight="16dip"
             android:focusable="true"
@@ -63,6 +67,8 @@
             android:id="@+id/year"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginTop="10dip"
+            android:layout_marginBottom="10dip"
             android:layout_marginLeft="16dip"
             android:layout_marginRight="16dip"
             android:focusable="true"
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
index 29c97b7..24b6194 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -30,6 +30,8 @@
         android:id="@+id/hour"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip"
         android:layout_marginLeft="16dip"
         android:layout_marginRight="14dip"
         android:focusable="true"
@@ -49,6 +51,8 @@
         android:id="@+id/minute"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip"
         android:layout_marginLeft="14dip"
         android:layout_marginRight="16dip"
         android:focusable="true"
@@ -60,6 +64,8 @@
         android:id="@+id/amPm"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip"
         android:layout_marginLeft="16dip"
         android:layout_marginRight="16dip"
         android:focusable="true"
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 4aa7dde..1649c48 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -843,6 +843,9 @@
              @hide -->
         <attr name="cantSaveState" format="boolean" />
         <attr name="uiOptions" />
+        <!-- Declare that your application will be able to deal with RTL (right to left) layouts.
+             If set to  false (default value), your application will not care about RTL layouts. -->
+        <attr name="supportsRtl" format="boolean" />
     </declare-styleable>
     
     <!-- The <code>permission</code> tag declares a security permission that can be
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b60cda7..e5f049d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -421,6 +421,7 @@
   <java-symbol type="string" name="date_picker_increment_year_button" />
   <java-symbol type="string" name="date_time" />
   <java-symbol type="string" name="date_time_set" />
+  <java-symbol type="string" name="date_time_done" />
   <java-symbol type="string" name="day_of_week_long_friday" />
   <java-symbol type="string" name="day_of_week_long_monday" />
   <java-symbol type="string" name="day_of_week_long_saturday" />
@@ -3550,6 +3551,8 @@
      =============================================================== -->
   <public type="attr" name="isolatedProcess" id="0x010103a7" />
 
+  <public type="attr" name="supportsRtl" id="0x010103a8" />
+
   <public type="attr" name="textDirection"/>
 
   <public type="attr" name="layoutDirection" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8919664..718de0a 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2816,6 +2816,8 @@
     <string name="date_picker_dialog_title">Set date</string>
     <!-- Name of the button in the date/time picker to accept the date/time change -->
     <string name="date_time_set">Set</string>
+    <!-- Name of the button in the date/time picker to accept the date/time change -->
+    <string name="date_time_done">Done</string>
 
     <!-- Security Permissions strings-->
     <!-- The default permission group for any permissions that have not explicitly set a group. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 288b8b2..baeb9cc 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1643,7 +1643,7 @@
         <item name="android:selectionDividerHeight">2dip</item>
         <item name="android:selectionDividersDistance">48dip</item>
         <item name="android:internalMinWidth">48dip</item>
-        <item name="android:internalMaxHeight">200dip</item>
+        <item name="android:internalMaxHeight">180dip</item>
         <item name="android:minFlingDistance">150dip</item>
     </style>
 
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index ef38a60..5ba6bf9 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -54,7 +54,7 @@
 # On space-constrained devices, we include a subset of fonts:
 ifeq ($(SMALLER_FONT_FOOTPRINT),true)
 droidsans_fallback_src := DroidSansFallback.ttf
-extra_droidsans_fonts := DroidSans.ttf DroidSans-Bold.ttf
+extra_font_files := DroidSans.ttf DroidSans-Bold.ttf
 else
 include $(CLEAR_VARS)
 LOCAL_MODULE := DroidSansEthiopic-Regular.ttf
@@ -64,8 +64,29 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
 include $(BUILD_PREBUILT)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := MTLmr3m.ttf
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := fallback_fonts-ja.xml
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+include $(BUILD_PREBUILT)
+
 droidsans_fallback_src := DroidSansFallbackFull.ttf
-extra_droidsans_fonts := DroidSans.ttf DroidSans-Bold.ttf DroidSansEthiopic-Regular.ttf
+extra_font_files := \
+	DroidSans.ttf \
+	DroidSans-Bold.ttf \
+	DroidSansEthiopic-Regular.ttf \
+	MTLmr3m.ttf \
+	fallback_fonts-ja.xml
 endif  # SMALLER_FONT_FOOTPRINT
 
 ################################
@@ -75,13 +96,13 @@
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-LOCAL_REQUIRED_MODULES := $(extra_droidsans_fonts)
+LOCAL_REQUIRED_MODULES := $(extra_font_files)
 include $(BUILD_PREBUILT)
 
 font_symlink_src :=
 font_symlink :=
 droidsans_fallback_src :=
-extra_droidsans_fonts :=
+extra_font_files :=
 
 ################################
 # Build the rest font files as prebuilt.
diff --git a/data/fonts/fallback_fonts-ja.xml b/data/fonts/fallback_fonts-ja.xml
new file mode 100644
index 0000000..62491d8
--- /dev/null
+++ b/data/fonts/fallback_fonts-ja.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Fallback Fonts
+
+    This file specifies the fonts, and the priority order, that will be searched for any
+    glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
+    Each entry consists of a family tag and a list of files (file names) which support that
+    family. The fonts for each family are listed in the order of the styles that they
+    handle (the order is: regular, bold, italic, and bold-italic). The order in which the
+    families are listed in this file represents the order in which these fallback fonts
+    will be searched for glyphs that are not supported by the default system fonts (which are
+    found in /system/etc/system_fonts.xml).
+
+    Note that there is not nameset for fallback fonts, unlike the fonts specified in
+    system_fonts.xml. The ability to support specific names in fallback fonts may be supported
+    in the future. For now, the lack of files entries here is an indicator to the system that
+    these are fallback fonts, instead of default named system fonts.
+
+    There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
+    provide references to other font families that should be used in addition to the default
+    fallback fonts. That file can also specify the order in which the fallback fonts should be
+    searched, to ensure that a vendor-provided font will be used before another fallback font
+    which happens to handle the same glyph.
+
+    Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
+    their ordering in the fallback or vendor files gives priority to the first in the list.
+    Locale-specific ordering can be configured by adding language and region codes to the end
+    of the filename (e.g. /system/etc/fallback_fonts-ja.xml). When no region code is used,
+    as with this example, all regions are matched. Use separate files for each supported locale.
+    The standard fallback file (fallback_fonts.xml) is used when a locale does not have its own
+    file. All fallback files must contain the same complete set of fonts; only their ordering
+    can differ.
+-->
+<familyset>
+    <family>
+        <fileset>
+            <file>DroidSansArabic.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansEthiopic-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansHebrew-Regular.ttf</file>
+            <file>DroidSansHebrew-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansThai.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansArmenian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansGeorgian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Lohit-Devanagari.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Lohit-Bengali.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>Lohit-Tamil.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>AndroidEmoji.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>MTLmr3m.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansFallback.ttf</file>
+        </fileset>
+    </family>
+</familyset>
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 63b3a58..ba01947 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -88,4 +88,9 @@
             <file>DroidSansFallback.ttf</file>
         </fileset>
     </family>
+    <family>
+        <fileset>
+            <file>MTLmr3m.ttf</file>
+        </fileset>
+    </family>
 </familyset>
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 458f85b..db26765 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -15,8 +15,8 @@
 # Warning: this is actually a product definition, to be inherited from
 
 PRODUCT_COPY_FILES := \
-    frameworks/base/data/fonts/system_fonts.xml:system/etc/system_fonts.xml \
-    frameworks/base/data/fonts/fallback_fonts.xml:system/etc/fallback_fonts.xml
+    frameworks/base/data/fonts/system_fonts.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/system_fonts.xml \
+    frameworks/base/data/fonts/fallback_fonts.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/fallback_fonts.xml
 
 PRODUCT_PACKAGES := \
     DroidSansFallback.ttf \
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 92bc83e..ba8dc5e 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -90,21 +90,20 @@
           <ul>
             <li>
                 <a href="<?cs var:toroot ?>guide/topics/providers/content-provider-basics.html">
-                    <span class="en">Content Provider Basics</span>
+                    <span class="en">Content Provider Basics<span
+class="new">&nbsp;new!</span></span>
                 </a>
-                <span class="new">new!</span>
             </li>
             <li>
                 <a href="<?cs var:toroot ?>guide/topics/providers/content-provider-creating.html">
-                    <span class="en">Creating a Content Provider</span>
+                    <span class="en">Creating a Content Provider<span
+class="new">&nbsp;new!</span></span>
                 </a>
-                <span class="new">new!</span>
             </li>
             <li>
                 <a href="<?cs var:toroot ?>guide/topics/providers/calendar-provider.html">
-                    <span class="en">Calendar Provider</span>
+                    <span class="en">Calendar Provider<span class="new">&nbsp;new!</span></span>
                 </a>
-                <span class="new">new!</span>
             </li>
           </ul>
       </li>
@@ -130,8 +129,8 @@
                 <span class="en">Input Events</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html">
-               <span class="en">Menus</span>
-              </a> <span class="new">updated</span></li>
+               <span class="en">Menus<span class="new">&nbsp;new!</span></span>
+              </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
                <span class="en">Action Bar</span>
               </a></li>
@@ -160,6 +159,19 @@
           <li><a href="<?cs var:toroot ?>guide/topics/ui/custom-components.html">
                 <span class="en">Custom Components</span>
               </a></li>
+          <li class="toggle-list">
+            <div><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/index.html">
+                <span class="en">Accessibility<span class="new">&nbsp;new!</span></span>
+            </a></div>
+            <ul>
+              <li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/apps.html">
+                <span class="en">Making Applications Accessible</span>
+              </a></li>
+              <li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/services.html">
+                <span class="en">Building Accessibility Services</span>
+              </a></li>
+            </ul>
+          </li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/binding.html">
                 <span class="en">Binding to Data with AdapterView</span>
               </a></li>
@@ -500,8 +512,7 @@
           <span class="en">Multiple APK Support</span></a>
       </li>
       <li><a href="<?cs var:toroot ?>guide/market/expansion-files.html">
-          <span class="en">APK Expansion Files</span></a>
-          <span class="new">new!</span>
+          <span class="en">APK Expansion Files<span class="new">&nbsp;new!</span></span></a>
       </li>
     </ul>
   </li>
@@ -833,9 +844,6 @@
       </li>
       </ul>
       <ul>
-      <li><a href="<?cs var:toroot ?>guide/practices/design/accessibility.html">
-            <span class="en">Designing for Accessibility</span>
-          </a></li>
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>guide/practices/design/performance.html">
             <span class="en">Designing for Performance</span>
diff --git a/docs/html/guide/practices/design/accessibility.html b/docs/html/guide/practices/design/accessibility.html
new file mode 100644
index 0000000..0fa7b32
--- /dev/null
+++ b/docs/html/guide/practices/design/accessibility.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+<meta http-equiv="refresh"
+content="0;url=http://developer.android.com/guide/topics/ui/accessibility/index.html">
+<title>Redirecting...</title>
+</head>
+<body>
+<p>You should be redirected. Please <a
+href="http://developer.android.com/guide/topics/ui/accessibility/index.html">click here</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/guide/practices/design/accessibility.jd b/docs/html/guide/practices/design/accessibility.jd
deleted file mode 100644
index 72da04e..0000000
--- a/docs/html/guide/practices/design/accessibility.jd
+++ /dev/null
@@ -1,352 +0,0 @@
-page.title=Designing for Accessibility
-@jd:body
-
-
-<div id="qv-wrapper">
-<div id="qv">
-
-  <h2>Quickview</h2>
-  <ul>
-    <li>To make your application more accessible, you should make sure your UI is navigable
-using a directional controller and your widgets provide content descriptions</li>
-    <li>If you implement a custom view, you should ensure that it delivers the appropriate
-accessibility events during user interaction</li>
-  </ul>
-
-  <h2>In this document</h2>
-  <ol>
-    <li><a href="#Navigation">Allow Navigation with a Directional Controller</a>
-      <ol>
-        <li><a href="#FocusOrder">Controlling focus order</a></li>
-        <li><a href="#ClickingDpad">Clicking with a directional controller</a></li>
-      </ol>
-    </li>
-    <li><a href="#LabelInputs">Label Your Input Widgets</a></li>
-    <li><a href="#UiBestPractices">Follow Android UI Best Practices</a></li>
-    <li><a href="#CustomViews">Send Accessibility Events from Custom View Components</a></li>
-    <li><a href="#Test">Test Your Application’s Accessibility</a></li>
-  </ol>
-
-  <h2>Key classes</h2>
-  <ol>
-    <li>{@link android.view.accessibility.AccessibilityEvent}</li>
-    <li>{@link android.view.accessibility.AccessibilityEventSource}</li>
-  </ol>
-
-  <h2>Related samples</h2>
-  <ol>
-    <li><a
-href="{@docRoot}resources/samples/AccessibilityService/index.html">Accessibility Service</a></li>
-  </ol>
-
-</div>
-</div>
-
-
-
-<p>Many Android users have disabilities that require them to interact with their Android devices in
-different ways.  These include users who have visual, physical or age-related disabilities that
-prevent them from fully using or seeing a touchscreen.</p>
-
-<p>Android provides an accessibility layer that helps these users navigate their Android-powered
-devices more easily.  Android's accessibility services provide things like text-to-speech, haptic
-feedback, and trackball/d-pad navigation that augment the user experience.</p>
-
-<p>Your application should follow the guidelines in this document to ensure that it provides a
-good experience for users with disabilities. Following these two basic rules will solve most
-access-related problems:</p>
-
-<ul>
-<li>Make all of your user interface controls accessible with a trackball or directional
-controller (d-pad).</li>
-<li>Label your {@link android.widget.ImageButton}, {@link android.widget.EditText}, and other input
-widgets using the <a
-href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code
-android:contentDescription}</a> attribute.</li>
-</ul>
-
-
-
-<h2 id="Navigation">Allow Navigation with a Directional Controller</h2>
-
-<p>Many Android devices come with some sort of directional controller, such as:</p>
-<ul>
-<li>A clickable trackball that users can move in any direction</li>
-<li>A clickable d-pad that allows users to navigate in four directions.</li>
-<li>Arrow keys and an OK button that’s equivalent to clicking a trackball or d-pad.</li>
-</ul>
-
-<p>All of these directional controllers allow users to navigate the screen without using the
-touchscreen. On some devices, a user can also navigate to the top or bottom of a list by holding
-down the <em>alt</em> key while pressing a discrete key for up or down.</p>
-
-<p>A directional controller is the primary means of navigation for users with visual or some
-physical impairments (and also for users without impairments when using devices that don't
-have a touchscreen). You should verify that all UI controls in your application are
-accessible without using the touchscreen and that clicking with the center button (or OK button) has
-the same effect as touching the controls on the touchscreen.</p>
-
-<p>A UI control (also called a "widget") is accessible using directional controls when it's
-"focusable" property is "true." This means that users can focus on the widget using the directional
-controls and then interact with it. Widgets provided by the Android APIs are focusable by default
-and visually indicate focus by changing the widget visual appearance in some way.</p>
-
-<p>Android provides several APIs that let you control whether a widget is focusable and even
-request that a widget be given focus. Such methods include:</p>
-
-<ul>
-  <li>{@link android.view.View#setFocusable setFocusable()}</li>
-  <li>{@link android.view.View#isFocusable isFocusable()}</li>
-  <li>{@link android.view.View#requestFocus requestFocus()}</li>
-</ul>
-
-<p>When working with a view that is not focusable by default, you can make it focusable from the XML
-layout file by setting the <a
-href="{@docRoot}reference/android/view/View.html#attr_android:focusable">{@code
-android:focusable}</a> attribute to {@code "true"}.</p>
-
-
-
-<h3 id="FocusOrder">Controlling focus order</h3>
-
-<p>When the user navigates in any direction using the directional controls, focus is passed from one
-view to another, as determined by the focus ordering. The ordering of the focus movement is based on
-an algorithm that finds the nearest neighbor in a given direction. In rare cases, the default
-algorithm may not match the order that you intended for your UI. In these situations, you can
-provide explicit overrides to the ordering using the following XML attributes in the layout
-file:</p>
-
-<dl>
- <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
->{@code android:nextFocusDown}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates down.</dd>
- <a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft"
->{@code android:nextFocusLeft}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates left.</dd>
- <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight"
->{@code android:nextFocusRight}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates right.</dd>
- <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
->{@code android:nextFocusUp}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates up.</dd>
-</dl>
-
-<p>For example, here is an XML layout that contains a focusable {@link android.widget.TextView}.
-While the {@link android.widget.TextView} is located to the right of the {@link
-android.widget.EditText}, it can now be reached by pressing the down arrow when focus is on the
-{@link android.widget.EditText}: </p>
-
-<pre>
-&lt;LinearLayout android:orientation="horizontal"
-              ... &gt;
-    &lt;EditText android:id="@+id/edit"
-              android:nextFocusDown=”@+id/text”
-              ... /&gt;
-    &lt;TextView android:id="@+id/text"
-              android:focusable=”true”
-              android:text="Hello, I am a focusable TextView"
-              android:nextFocusUp=”@id/edit”
-              ... /&gt;
-&lt;/LinearLayout&gt;
-</pre>
-
-<p>When modifying this ordering, be sure that the navigation works as expected in all directions
-from each widget and when navigating in reverse (to get back to where you came from).</p>
-
-<p>You can also modify the focus ordering at runtime, using methods in the {@link
-android.view.View} class, such as {@link android.view.View#setNextFocusDownId
-setNextFocusDownId()} and  {@link android.view.View#setNextFocusRightId
-setNextFocusRightId()}.</p>
-
-
-<h3 id="ClickingDpad">Clicking with a directional controller</h3>
-
-<p>On most devices, clicking a view using a directional controller sends a {@link
-android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
-in focus. Make sure this event has the same effect as touching the view on the touchscreen. All
-standard Android views already handle {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}
-appropriately.</p>
-
-<p>If possible, also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the same as
-{@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}.  That makes interaction much easier from a full
-keyboard.</p>
-
-
-
-
-<h2 id="LabelInputs">Label Your Input Widgets</h2>
-
-<p>Many input widgets rely on visual cues to inform the user of their meaning.  For example, a
-notepad application might use an {@link android.widget.ImageButton} with a picture of a plus sign to
-indicate that the user can add a new note.  Or, an {@link android.widget.EditText} may have
-a label near it that indicates its purpose.  When a visually impaired user accesses your
-application, these visual cues are often useless.</p>
-
-<p>To provide textual information about these widgets (as an alternative to the visual cues), you
-should use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"
->{@code android:contentDescription}</a> attribute. The text you provide in this attribute
-is not visible on the screen, but if a user has enabled accessibility speech tools then the
-description in this attribute is read aloud to the user.</p>
-
-<p>You should set the <a
-href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription" >{@code
-android:contentDescription}</a> attribute on every {@link android.widget.ImageButton}, {@link
-android.widget.EditText}, {@link android.widget.CheckBox}, and on any other input widgets that might
-benefit users with extra information.</p>
-
-<p>For example, the following {@link android.widget.ImageButton} sets the content description for
-the plus button to the {@code add_note} string resource, which might be defined in English as
-“Add note":</p>
-
-<pre>
-&lt;ImageButton
-    android:id=”@+id/add_entry_button”
-    android:src=”@drawable/plus”
-    android:contentDescription=”@string/add_note”/&gt;
-</pre>
-
-<p>This way, when using speech accessibility tools, the user hears "Add note" when focused on
-this widget.</p>
-
-
-
-<h2 id="UiBestPractices">Follow Android UI Best Practices</h2>
-
-<p>You can make it easier for users to learn how to use your application by developing a user
-interface that complies with Android's standard interaction patterns, instead of creating your own
-or using interaction patterns from another platform. This consistency is especially important for
-many disabled users, as they may have less contextual information available to try to understand
-your application’s interface.</p>
-
-<p>Specifically, you should:</p>
-
-<ul>
-<li>Use the platform's built-in widgets and layouts whenever possible, as these views provide
-accessibility support by default.</li>
-<li>Use the <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> as an
-alternative to complex touchscreen tasks.</li>
-<li>Make sure the BACK button correctly moves the user back one logical step in the <a
-href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">task's back stack</a> or the
-activity's back stack of fragments (when <a
-href="{@docRoot}guide/topics/fundamentals/fragments.html#Transactions">performing fragment
-transactions</a>), as appropriate.</li>
-</ul>
-
-
-
-<h2 id="CustomViews">Send Accessibility Events from Custom View Components</h2>
-
-<p>If your application requires that you create a <a
-href="{@docRoot}guide/topics/ui/custom-components.html">custom view component</a>, you may need to
-do some additional work to ensure that your view is accessible.  Specifically, you should make sure
-that your view implements the {@link android.view.accessibility.AccessibilityEventSource}
-interface and emits {@link android.view.accessibility.AccessibilityEvent}s at the proper times,
-and that each {@link android.view.accessibility.AccessibilityEvent} contains relevant information
-about the state of the view.</p>
-
-<p>Events are emitted whenever something notable happens in the user interface.  Currently, there
-are five types of accessibility events that a view should send to the system as the user interacts
-with it:</p>
-
-<dl>
-<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</dt>
-<dd>Indicates that the user clicked on the view (for example, the user selects a button).</dd>
-
-<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</dt>
-<dd>Indicates that the user performed a long press on the view. </dd>
-
-<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED}</dt>
-<dd>Indicates that the user selected an item from within the view. This is usually used in the
-context of an {@link android.widget.AdapterView}.</dd>
-
-<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</dt>
-<dd>Indicates that the user moved the focus to the view.</dd>
-
-<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}</dt>
-<dd>Indicates that the text or contents of the view changed.</dd>
-</dl>
-
-
-<p>The basic {@link android.view.View} class implements {@link
-android.view.accessibility.AccessibilityEventSource} and emits these events at the proper time in
-the standard cases.  Your custom view should extend from {@link android.view.View} (or one of its
-subclasses) to take advantage of these default implementations.</p>
-
-<p>Depending on the specifics of your custom view, your view may need to emit one of these events at
-a different time than the default {@link android.view.View} implementation.  To do so, simply call
-{@link android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
-sendAccessibilityEvent()} with the specific event type at the correct time.</p>
-
-<p>For example, say you are implementing a custom slider bar that allows the user to select a
-numeric value by pressing the left or right arrows.  This view should emit an event of type {@link
-android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider value
-changes:</p>
-
-<pre>
-&#64;Override
-public boolean onKeyUp (int keyCode, KeyEvent event) {
-  if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
-    mCurrentValue--;
-    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
-    return true;
-  }
-  ...
-}
-</pre>
-
-<p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that
-describe the current state of the view.  These properties include things like the view’s class name,
-text and checked state.  The specific properties required for each event type are described in the
-{@link android.view.accessibility.AccessibilityEvent} documentation.  The {@link android.view.View}
-implementation will fill in default values for these properties. Most of these values, like the
-class name and event timestamp, will not need to be changed. However, depending on the specifics of
-your custom view, you may want to provide a different value for one or more of the properties.  For
-example, your view may have additional state information that you want to add to the event text.</p>
-
-<p>The {@link android.view.View#dispatchPopulateAccessibilityEvent
-dispatchPopulateAccessibilityEvent()} method in {@link android.view.View} provides a hook for making
-changes to the {@link android.view.accessibility.AccessibilityEvent} object before it is
-emitted.</p>
-
-<p>In the above slider bar example, the view should add the current value of the slider bar to the
-text of the event:</p>
-
-<pre>
-&#64;Override
-public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
-  super.dispatchPopulateAccessibilityEvent(event);
-  if (!isShown()) {
-    return false;
-  }
-  CharSequence text = String.valueOf(mCurrentValue);
-  if (text.length() > AccessibilityEvent.MAX_TEXT_LENGTH) {
-    text = text.subSequence(0, AccessiblityEvent.MAX_TEXT_LENGTH);
-  }
-  event.getText().add(text);
-  return true;
-}
-</pre>
-
-
-<h2 id="Test">Test Your Application’s Accessibility</h2>
-
-<p>You can simulate the experience for many users by enabling an accessibility service that speaks
-as you move around the screen.  One such service is <a
-href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">TalkBack</a>, by the
-<a href="http://code.google.com/p/eyes-free/">Eyes-Free Project</a>.  It comes preinstalled on many
-Android-powered devices, but is also available for free from the <a
-href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">Google Play</a> store.</p>
-
-<p>This service requires that you have a text-to-speech engine installed on your phone.  You can
-verify if you have one installed in the <strong>Text-to-speech</strong> settings menu by selecting
-<strong>Listen to an example</strong>. If you do not hear anything spoken, install the required
-voice data by selecting <strong>Install voice data</strong>.</p>
-
-<p>Once text-to-speech is functioning correctly, you can enable TalkBack (or another accessibility
-service) in the <strong>Accessibility</strong> settings menu.  Enable both
-<strong>Accessibility</strong> and <strong>TalkBack</strong>.  As you navigate about the device, you
-should now hear spoken feedback.</p>
-
-<p>You can now attempt to use your application as a blind user would.  As you move around using only
-the directional controller, make sure that the spoken feedback you hear makes sense and is
-sufficient to navigate the application without any visual cues.</p>
diff --git a/docs/html/guide/topics/ui/accessibility/apps.jd b/docs/html/guide/topics/ui/accessibility/apps.jd
new file mode 100644
index 0000000..ff34be6
--- /dev/null
+++ b/docs/html/guide/topics/ui/accessibility/apps.jd
@@ -0,0 +1,570 @@
+page.title=Making Applications Accessible
+parent.title=Accessibility
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>In this document</h2>
+  <ol>
+    <li><a href="#label-ui">Labeling User Interface Elements</a></li>
+    <li><a href="#focus-nav">Enabling Focus Navigation</a>
+      <ol>
+        <li><a href="#focus-enable">Enabling view focus</a></li>
+        <li><a href="#focus-order">Controlling focus order</a></li>
+      </ol>
+    </li>
+    <li><a href="#custom-views">Building Accessible Custom Views</a>
+      <ol>
+        <li><a href="#directional-control">Handling directional controller clicks</a></li>
+        <li><a href="#accessibility-methods">Implementing accessibility API methods</a></li>
+        <li><a href="#send-events">Sending accessibility events</a></li>
+        <li><a href="#populate-events">Populating accessibility events</a></li>
+      </ol>
+    </li>
+    <li><a href="#test">Testing Accessibility</a>
+      <ol>
+        <li><a href="#test-audibles">Testing audible feedback</a></li>
+        <li><a href="#test-navigation">Testing focus navigation</a></li>
+      </ol>
+    </li>
+  </ol>
+
+  <h2>Key classes</h2>
+  <ol>
+    <li>{@link android.view.accessibility.AccessibilityEvent}</li>
+    <li>{@link android.view.accessibility.AccessibilityNodeInfo}</li>
+    <li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}</li>
+    <li>{@link android.view.View.AccessibilityDelegate}</li>
+    <li>{@link android.support.v4.view.AccessibilityDelegateCompat}</li>
+  </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
+    <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a>
+      </li>
+    <li><a href="{@docRoot}design/index.html">Android Design</a></li>
+  </ol>
+
+</div>
+</div>
+
+<p>Applications built for Android are accessible to users with visual, physical or age-related
+disabilities when they activate accessibility features and services on a device. By default,
+these services make your application more accessible. However, there are further steps you should
+take to optimize the accessibility of your application and ensure a pleasant experience for all your
+users.</p>
+
+<p>Making sure your application is accessible to all users is relatively easy, particularly when you
+use framework-provided user interface components. If you only use these standard components for your
+application, there are just a few steps required to ensure your application is accessible:</p>
+
+<ol>
+  <li>Label your {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link
+android.widget.EditText}, {@link android.widget.CheckBox} and other user interface controls using
+the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+    {@code android:contentDescription}</a> attribute.</li>
+  <li>Make all of your user interface elements accessible with a directional controller,
+    such as a trackball or D-pad.</li>
+  <li>Test your application by turning on accessibility services like TalkBack and Explore by
+    Touch, and try using your application using only directional controls.</li>
+</ol>
+
+<p>Developers who create custom controls that extend from the {@link android.view.View} class have
+some additional responsibilities for making sure their components are accessible for users. This
+document also discusses how to make custom view controls compatible with accessibility services.</p>
+
+
+<h2 id="label-ui">Labeling User Interface Elements</h2>
+
+<p>Many user interface controls rely on visual cues to inform users of their meaning. For
+example, a note-taking application might use an {@link android.widget.ImageButton} with a
+picture of a plus sign to indicate that the user can add a new note. Or, an {@link
+android.widget.EditText} component may have a label near it that indicates its purpose. When a user
+with impaired vision accesses your application, these visual cues are often useless.</p>
+
+<p>To provide textual information about interface controls (as an alternative to the visual cues),
+use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+{@code android:contentDescription}</a> attribute. The text you provide in this attribute is not
+visible on the screen, but if a user has enabled accessibility services that provide audible
+prompts, then the description in this attribute is read aloud to the user.</p>
+
+<p>Set the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+{@code android:contentDescription}</a> attribute for every {@link android.widget.ImageButton},
+{@link android.widget.ImageView}, {@link android.widget.EditText}, {@link android.widget.CheckBox}
+in your application's user interface, and on any other input controls that might require additional
+information for users who are not able to see it.</p>
+
+<p>For example, the following {@link android.widget.ImageButton} sets the content description for
+the plus button to the {@code add_note} string resource, which could be defined as “Add note" for an
+English language interface:</p>
+
+<pre>
+&lt;ImageButton
+    android:id=”@+id/add_note_button”
+    android:src=”@drawable/add_note”
+    android:contentDescription=”@string/add_note”/&gt;
+</pre>
+
+<p>By including the description, speech-based accessibility services can announce "Add note" when a
+user moves focus to this button or hovers over it.</p>
+
+<p class="note">Note: For {@link android.widget.EditText} fields, provide an
+<a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a>
+attribute to help users understand what content is expected.</p>
+
+<h2 id="focus-nav">Enabling Focus Navigation</h2>
+
+<p>Focus navigation allows users with disabilities to step through user interface controls using a
+directional controller. Directional controllers can be physical, such as a clickable trackball,
+directional pad (D-Pad) or arrow keys, tab key navigation with an attached keyboard or a software
+application that provides an on-screen directional control.</p>
+
+<p>A directional controller is a primary means of navigation for many users.
+Verify that all user interface (UI) controls in your application are accessible
+without using the touchscreen and that clicking with the center button (or OK button) of a
+directional controller has the same effect as touching the controls on the touchscreen. For
+information on testing directional controls, see <a href="#test-navigation">Testing focus
+navigation</a>.</p>
+
+<h3 id="focus-enable">Enabling view focus</h3>
+
+<p>A user interface element is accessible using directional controls when its
+<a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
+{@code android:focusable}</a> attribute is set to {@code true}. This setting allows users to focus
+on the element using the directional controls and then interact with it. The user interface controls
+provided by the Android framework are focusable by default and visually indicate focus by changing
+the control’s appearance.</p>
+
+<p>Android provides several APIs that let you control whether a user interface control is focusable
+and even request that a control be given focus:</p>
+
+<ul>
+  <li>{@link android.view.View#setFocusable setFocusable()}</li>
+  <li>{@link android.view.View#isFocusable isFocusable()}</li>
+  <li>{@link android.view.View#requestFocus requestFocus()}</li>
+</ul>
+
+<p>When working with a view that is not focusable by default, you can make it focusable from the XML
+layout file by setting the
+<a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
+{@code android:focusable}</a> attribute to {@code true} or by using the {@link
+android.view.View#setFocusable setFocusable()} method.</p>
+
+<h3 id="focus-order">Controlling focus order</h3>
+
+<p>When users navigate in any direction using directional controls, focus is passed from one
+user interface element (View) to another, as determined by the focus ordering. The ordering of the
+focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In
+rare cases, the default algorithm may not match the order that you intended for your UI. In these
+situations, you can provide explicit overrides to the ordering using the following XML attributes in
+the layout file:</p>
+
+<dl>
+ <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
+>{@code android:nextFocusDown}</a></dt>
+  <dd>Defines the next view to receive focus when the user navigates down.</dd>
+ <a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft"
+>{@code android:nextFocusLeft}</a></dt>
+  <dd>Defines the next view to receive focus when the user navigates left.</dd>
+ <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight"
+>{@code android:nextFocusRight}</a></dt>
+  <dd>Defines the next view to receive focus when the user navigates right.</dd>
+ <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
+>{@code android:nextFocusUp}</a></dt>
+  <dd>Defines the next view to receive focus when the user navigates up.</dd>
+</dl>
+
+<p>The following example XML layout shows two focusable user interface elements where the <a
+href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
+>{@code android:nextFocusDown}</a> and <a
+href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
+>{@code android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is
+located to the right of the {@link android.widget.EditText}. However, since these properties have
+been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow
+when focus is on the {@link android.widget.EditText} element: </p>
+
+<pre>
+&lt;LinearLayout android:orientation="horizontal"
+        ... &gt;
+    &lt;EditText android:id="@+id/edit"
+        android:nextFocusDown=”@+id/text”
+        ... /&gt;
+    &lt;TextView android:id="@+id/text"
+        android:focusable=”true”
+        android:text="Hello, I am a focusable TextView"
+        android:nextFocusUp=”@id/edit”
+        ... /&gt;
+&lt;/LinearLayout&gt;
+</pre>
+
+<p>When modifying focus order, be sure that the navigation works as expected in all directions from
+each user interface control and when navigating in reverse (to get back to where you came from).</p>
+
+<p class="note"><strong>Note:</strong> You can modify the focus order of user interface components
+at runtime, using methods such as {@link android.view.View#setNextFocusDownId setNextFocusDownId()}
+and {@link android.view.View#setNextFocusRightId setNextFocusRightId()}.</p>
+
+
+<h2 id="custom-views">Building Accessible Custom Views</h2>
+
+<p>If your application requires a <a href="{@docRoot}guide/topics/ui/custom-components.html">custom
+view component</a>, you must do some additional work to ensure that your custom view is accessible.
+These are the main tasks for ensuring the accessibility of your view:</p>
+
+<ul>
+  <li>Handle directional controller clicks</li>
+  <li>Implement Accessibility API methods</li>
+  <li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom view</li>
+  <li>Populate {@link android.view.accessibility.AccessibilityEvent} and {@link
+    android.view.accessibility.AccessibilityNodeInfo} for your view</li>
+</ul>
+
+
+<h3 id="directional-control">Handling directional controller clicks</h3>
+
+<p>On most devices, clicking a view using a directional controller sends a {@link
+android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
+in focus. All standard Android views already handle {@link
+android.view.KeyEvent#KEYCODE_DPAD_CENTER} appropriately. When building a custom {@link
+android.view.View} control, make sure this event has the same effect as touching the view on the
+touchscreen. </p>
+
+<p>Your custom control should also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the
+same as {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. This approach makes interaction from a
+full keyboard much easier for users.</p>
+
+
+<h3 id="accessibility-methods">Implementing accessibility API methods</h3>
+
+<p>Accessibility events are messages about users interaction with visual interface components in
+your application. These messages are handled by <a href="services.html">Accessibility Services</a>,
+which use the information in these events to produce supplemental feedback and prompts when users
+have enabled accessibility services. As of Android 4.0 (API Level 14) and higher, the methods for
+generating accessibility events have been expanded to provide more detailed information beyond the
+{@link android.view.accessibility.AccessibilityEventSource} interface introduced in Android 1.6 (API
+Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well
+as the {@link android.view.View.AccessibilityDelegate} class. The methods are as follows:</p>
+
+<dl>
+ <dt>{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}</dt>
+  <dd>(API Level 4) This method is called when a user takes action on a view. The event is
+classified with a user action type such as {@link
+android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED TYPE_VIEW_CLICKED}. You typically do
+not need to implement this method unless you are creating a custom view.</dd>
+
+  <dt>{@link android.view.View#sendAccessibilityEventUnchecked
+sendAccessibilityEventUnchecked()}</dt>
+  <dd>(API Level 4) This method is used when the calling code needs to directly control the check
+for accessibility being enabled on the device ({@link
+android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If
+you do implement this method, you must assume that the calling method has already checked that
+accessibility is enabled and the result is {@code true}. You typically do not need to implement this
+method for a custom view.</dd>
+
+  <dt>{@link android.view.View#dispatchPopulateAccessibilityEvent
+dispatchPopulateAccessibilityEvent()} </dt>
+  <dd>(API Level 4) The system calls this method when your custom view generates an
+accessibility event. As of API Level 14, the default implementation of this method calls {@link
+android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and
+then the {@link android.view.View#dispatchPopulateAccessibilityEvent
+dispatchPopulateAccessibilityEvent()} method for each child of this view. In order to support
+accessibility services on revisions of Android <em>prior</em> to 4.0 (API Level 14) you
+<em>must</em> override this method and populate {@link
+android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom
+view.</dd>
+
+  <dt>{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}</dt>
+  <dd>(API Level 14) This method sets the text output of an {@link
+android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the
+view is a child of a view which generates an accessibility event.
+
+  <p class="note"><strong>Note:</strong> Modifying additional attributes beyond the text within
+this method potentially overwrites properties set by other methods. So, while you are able modify
+attributes of the accessibility event with this method, you should limit these changes
+to text content only and use the {@link android.view.View#onInitializeAccessibilityEvent
+onInitializeAccessibilityEvent()} method to modify other properties of the event.</p>
+
+  <p class="note"><strong>Note:</strong> If your implementation of this event calls for completely
+overiding the output text without allowing other parts of your layout to modify its content, then
+do not call the super implementation of this method in your code.</p>
+  </dd>
+
+  <dt>{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}</dt>
+  <dd>(API Level 14) The system calls this method to obtain additional information about the
+state of the view, beyond text content. If your custom view provides interactive control beyond a
+simple {@link android.widget.TextView} or {@link android.widget.Button}, you should override this
+method and set the additional information about your view into the event using this method, such as
+password field type, checkbox type or states that provide user interaction or feedback. If you
+do override this method, you must call its super implementation and then only modify properties
+that have not been set by the super class.</dd>
+
+  <dt>{@link android.view.View#onInitializeAccessibilityNodeInfo
+onInitializeAccessibilityNodeInfo()}</dt>
+  <dd>(API Level 14) This method provides accessibility services with information about the state of
+the view. The default {@link android.view.View} implementation sets a standard set of view
+properties, but if your custom view provides interactive control beyond a simple {@link
+android.widget.TextView} or {@link android.widget.Button}, you should override this method and set
+the additional information about your view into the {@link
+android.view.accessibility.AccessibilityNodeInfo} object handled by this method.</dd>
+
+  <dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent
+onRequestSendAccessibilityEvent()}</dt>
+  <dd>(API Level 14) The system calls this method when a child of your view has generated an
+{@link android.view.accessibility.AccessibilityEvent}. This step allows the the parent view to amend
+the accessibility event with additional information. You should implement this method only if your
+custom view can have child views and if the parent view can provide context information to the
+accessibility event that would be useful to accessibility services.</dd>
+</dl>
+
+<p>In order to support these accessibility methods for a custom view, you should take one of the
+following approaches:</p>
+
+<ul>
+  <li>If your application targets Android 4.0 (API level 14) and higher, override and implement the
+accessibility methods listed above directly in your custom view class.</li>
+  <li>If your custom view is intended to be compatible with Android 1.6 (API Level 4) and above, add
+the Android <a href="{@docRoot}sdk/compatibility-library.html">Support Library</a>, revision 5 or
+higher, to your project. Then, within your custom view class, call the
+{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
+ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods
+above. For an example of this approach, see the Android Support Library (revision 5 or higher)
+sample {@code AccessibilityDelegateSupportActivity} in 
+({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/})
+  </li>
+</ul>
+
+<p>In either case, you should implement the following accessibility methods for your custom view
+class:</p>
+
+<ul>
+  <li>{@link android.view.View#dispatchPopulateAccessibilityEvent
+    dispatchPopulateAccessibilityEvent()}</li>
+  <li>{@link android.view.View#onPopulateAccessibilityEvent
+    onPopulateAccessibilityEvent()}</li>
+  <li>{@link android.view.View#onInitializeAccessibilityEvent
+    onInitializeAccessibilityEvent()}</li>
+  <li>{@link android.view.View#onInitializeAccessibilityNodeInfo
+    onInitializeAccessibilityNodeInfo()}</li>
+</ul>
+
+<p>For more information about implementing these methods, see <a href="#populate-events">Populating
+Accessibility Events</a>.</p>
+
+
+<h3 id="send-events">Sending accessibility events</h3>
+
+<p>Depending on the specifics of your custom view, it may need to send {@link
+android.view.accessibility.AccessibilityEvent} objects at a different times or for events not
+handled by the default implementation. The {@link android.view.View} class provides a default
+implementation for these event types:</p>
+
+<ul>
+  <li>Starting with API Level 4:
+    <ul>
+      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</li>
+
+      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li>
+
+      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</li>
+    </ul>
+  </li>
+  <li>Starting with API Level 14:
+    <ul>
+      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED}</li>
+
+      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li>
+
+      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li>
+    </ul>
+  </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Hover events are associated with the Explore by
+Touch feature, which uses these events as triggers for providing audible prompts for user interface
+elements.</p>
+
+<p>In general, you should send an {@link android.view.accessibility.AccessibilityEvent} whenever the
+content of your custom view changes. For example, if you are implementing a custom slider bar that
+allows a user to select a numeric value by pressing the left or right arrows, your custom view
+should emit an event of type {@link
+android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider
+value changes. The following sample code demonstrates the use of the {@link
+android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
+sendAccessibilityEvent()} method to report this event.</p>
+
+<pre>
+&#64;Override
+public boolean onKeyUp (int keyCode, KeyEvent event) {
+    if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+        mCurrentValue--;
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+        return true;
+    }
+    ...
+}
+</pre>
+
+
+<h3 id="populate-events">Populating accessibility events</h3>
+
+<p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that
+describe the current state of the view. These properties include things such as the view’s class
+name, content description and checked state. The specific properties required for each event type
+are described in the {@link android.view.accessibility.AccessibilityEvent} reference documentation.
+The {@link android.view.View} implementation provides default values for these properties. Many of
+these values, including the class name and event timestamp, are provided automatically. If you are
+creating a custom view component, you must provide some information about the content and
+characteristics of the view. This information may be as simple as a button label, but may also
+include additional state information that you want to add to the event.</p>
+
+<p>The minimum requirement for providing information to accessibility services with a custom
+view is to implement {@link android.view.View#dispatchPopulateAccessibilityEvent
+dispatchPopulateAccessibilityEvent()}. This method is called by the system to request
+information for an {@link android.view.accessibility.AccessibilityEvent} and makes your custom
+view compatible with accessibility services on Android 1.6 (API Level 4) and higher. The
+following example code demonstrates a basic implementation of this method.</p>
+
+<pre>
+&#64;Override
+public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+    super.dispatchPopulateAccessibilityEvent(event);
+    // Call the super implementation to populate its text to the event, which
+    // calls onPopulateAccessibilityEvent() on API Level 14 and up.
+
+    // In case this is running on a API revision earlier that 14, check
+    // the text content of the event and add an appropriate text
+    // description for this custom view:
+    CharSequence text = getText();
+    if (!TextUtils.isEmpty(text)) {
+        event.getText().add(text);
+    }
+}
+</pre>
+
+<p>On Android 4.0 (API Level 14) and higher, the {@link
+android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
+{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
+methods are the recommended way to populate or modify the information in an {@link
+android.view.accessibility.AccessibilityEvent}. Use the 
+{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method
+specifically for adding or modifying the text content of the event, which is turned into audible
+prompts by accessibility services such as TalkBack. Use the
+{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for
+populating additional information about the event, such as the selection state of the view.</p>
+
+<p>In addition, you should also implement the
+{@link android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()}
+method. {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
+are used by accessibility services to investigate the view hierarchy that generated an accessibility
+event after receiving that event, to obtain a more detailed context information and provide
+appropriate feedback to users.</p>
+
+<p>The example code below shows how override these three methods by using
+{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
+ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android
+<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> for API Level 4 (revision 5
+or higher) is added to your project.</p>
+
+<pre>
+ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() {
+    &#64;Override
+    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(host, event);
+        // We call the super implementation to populate its text for the
+        // event. Then we add our text not present in a super class.
+        // Very often you only need to add the text for the custom view.
+        CharSequence text = getText();
+        if (!TextUtils.isEmpty(text)) {
+            event.getText().add(text);
+        }
+    }
+    &#64;Override
+    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(host, event);
+        // We call the super implementation to let super classes
+        // set appropriate event properties. Then we add the new property
+        // (checked) which is not supported by a super class.
+        event.setChecked(isChecked());
+    }
+    &#64;Override
+    public void onInitializeAccessibilityNodeInfo(View host,
+            AccessibilityNodeInfoCompat info) {
+        super.onInitializeAccessibilityNodeInfo(host, info);
+        // We call the super implementation to let super classes set
+        // appropriate info properties. Then we add our properties
+        // (checkable and checked) which are not supported by a super class.
+        info.setCheckable(true);
+        info.setChecked(isChecked());
+        // Quite often you only need to add the text for the custom view.
+        CharSequence text = getText();
+        if (!TextUtils.isEmpty(text)) {
+            info.setText(text);
+        }
+    }
+}
+</pre>
+
+<p>On applications targeting Android 4.0 (API Level 14) and higher, these methods can be implemented
+directly in your custom view class. For another example of this approach, see the Android
+<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> (revision 5 or higher) sample
+{@code AccessibilityDelegateSupportActivity} in 
+({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/}).</p>
+
+<p class="note"><strong>Note:</strong> You may find information on implementing accessibility for
+custom views written prior to Android 4.0 that describes the use of the
+{@link android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}
+method for populating AccessibilityEvents. As of the Android 4.0 release, however, the recommended
+approach is to use the
+{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
+{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
+methods.</p>
+
+
+<h2 id="test">Testing Accessibility</h2>
+
+<p>Testing the accessibility of your application is an important part of ensuring your users have a
+great experience. You can test the most important parts of accessibility by testing your application
+with audible feedback enabled and testing navigation within your application using directional
+controls.</p>
+
+<h3 id="test-audibles">Testing audible feedback</h3>
+<p>You can simulate the experience for many users by enabling an accessibility service that speaks
+as you move around the screen. The Explore by Touch accessibility service, which is available on
+devices with Android 4.0 and later. The <a
+href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
+accessibility service, by the <a href="http://code.google.com/p/eyes-free/">Eyes-Free
+Project</a> comes preinstalled on many Android devices.</p>
+
+<p>To enable TalkBack on revisions of Android prior to Android 4.0:</p>
+<ol>
+  <li>Launch the Settings application.</li>
+  <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
+  <li>Select <strong>Accessibility</strong> to enable it.</li>
+  <li>Select <strong>TalkBack</strong> to enable it.</li>
+</ol>
+
+<p class="note"><strong>Note:</strong> If the TalkBack accessibility service is not available, you
+can install it for free from <a href="http://play.google.com">Google Play</a>.</p>
+
+<p>To enable Explore by Touch on Android 4.0 and later:</p>
+<ol>
+  <li>Launch the Settings application.</li>
+  <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
+  <li>Select the <strong>TalkBack</strong> to enable it.</li>
+  <li>Return to the <strong>Accessibility</strong> category and select <strong>Explore by
+Touch</strong> to enable it.
+    <p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this
+option is not available.</p>
+  </li>
+</ol>
+
+<h3 id="test-navigation">Testing focus navigation</h3>
+
+<p>As part of your accessibility testing, you can test navigation of your application using focus,
+even if your test devices does not have a directional controller. The <a
+href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> provides a
+simulated directional controller that you can easily use to test navigation. You can also use the
+arrow keys and Enter key on your keyboard with the Emulator to simulate use of a D-pad.</p>
diff --git a/docs/html/guide/topics/ui/accessibility/index.jd b/docs/html/guide/topics/ui/accessibility/index.jd
new file mode 100644
index 0000000..414d5f3
--- /dev/null
+++ b/docs/html/guide/topics/ui/accessibility/index.jd
@@ -0,0 +1,55 @@
+page.title=Accessibility
+parent.title=User Interface
+parent.link=../index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>Topics</h2>
+  <ol>
+  <li><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>
+    </li>
+  <li><a href="{@docRoot}guide/topics/ui/accessibility/services.html">Building Accessibility
+    Services</a></li>
+  </ol>
+
+  <h2>Key classes</h2>
+  <ol>
+    <li>{@link android.view.accessibility.AccessibilityEvent}</li>
+    <li>{@link android.accessibilityservice.AccessibilityService}</li>
+  </ol>
+  
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
+  </ol>
+
+</div>
+</div>
+
+<p>Many Android users have disabilities that require them to interact with their Android devices in
+different ways. These include users who have visual, physical or age-related disabilities that
+prevent them from fully seeing or using a touchscreen.</p>
+
+<p>Android provides accessibility features and services for helping these users navigate their
+devices more easily, including text-to-speech, haptic feedback, trackball and D-pad navigation that
+augment their experience. Android application developers can take advantage of these services to
+make their applications more accessible and also build their own accessibility services.</p>
+
+<p>The following topics show you how to use the Android framework to make applications more
+accessible.</p>
+
+<dl>
+  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications
+Accessible</a></strong>
+  </dt>
+  <dd>Development practices and API features to ensure your application is accessible to users with
+disabilities.</dd>
+
+  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/service.html">Building Accessibility
+Services</a></strong>
+  </dt>
+  <dd>How to use API features to build services that make other applications more accessible for
+users.</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/guide/topics/ui/accessibility/services.jd b/docs/html/guide/topics/ui/accessibility/services.jd
new file mode 100644
index 0000000..0dad4ec
--- /dev/null
+++ b/docs/html/guide/topics/ui/accessibility/services.jd
@@ -0,0 +1,290 @@
+page.title=Building Accessibility Services
+parent.title=Accessibility
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>Topics</h2>
+  <ol>
+    <li><a href="#manifest">Manifest Declarations and Permissions</a>
+      <ol>
+        <li><a href="service-declaration">Accessibility service declaration</a></li>
+        <li><a href="#service-config">Accessibility service configuration</a></li>
+      </ol>
+    </li>
+    <li><a href="#methods">AccessibilityService Methods</a></li>
+    <li><a href="#event-details">Getting Event Details</a></li>
+    <li><a href="#examples">Example Code</a></li>
+  </ol>
+
+  <h2>Key classes</h2>
+  <ol>
+    <li>{@link android.accessibilityservice.AccessibilityService}</li>
+    <li>{@link android.accessibilityservice.AccessibilityServiceInfo}</li>
+    <li>{@link android.view.accessibility.AccessibilityEvent}</li>
+    <li>{@link android.view.accessibility.AccessibilityRecord}</li>
+    <li>{@link android.view.accessibility.AccessibilityNodeInfo}</li>
+  </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
+  </ol>
+
+</div>
+</div>
+
+<p>An accessibility service is an application that provides user interface enhancements to
+assist users with disabilities, or who may temporarily be unable to fully interact with a device.
+For example, users who are driving, taking care of a young child or attending a very loud party
+might need additional or alternative interface feedback.</p>
+
+<p>Android provides standard accessibility services, including TalkBack, and developers can
+create and distribute their own services. This document explains the basics of building an
+accessibility service.</p>
+
+<p>The ability for you to build and deploy accessibility services was introduced with Android
+1.6 (API Level 4) and received significant improvements with Android 4.0 (API Level 14). The Android
+Support Library was also updated with the release of Android 4.0 to provide support for these
+enhanced accessibility features back to Android 1.6. Developers aiming for widely compatible
+accessibility services are encouraged to use the
+<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> and develop for the more
+advanced accessibility features introduced in Android 4.0.</p>
+
+
+<h2 id="manifest">Manifest Declarations and Permissions</h2>
+
+<p>Applications that provide accessibility services must include specific declarations in their
+ application manifests in order to be treated as an accessibility service by an Android system.
+ This section explains the required and optional settings for accessibility services.</p>
+
+
+<h3 id="service-declaration">Accessibility service declaration</h3>
+
+<p>In order to be treated as an accessibility service, your application must include the
+{@code service} element (rather than the {@code activity} element) within the {@code application}
+element in its manifest. In addition, within the {@code service} element, you must also include an
+accessibility service intent filter, as shown in the following sample:</p>
+
+<pre>
+&lt;application&gt;
+  &lt;service android:name=&quot;.MyAccessibilityService&quot;
+      android:label=&quot;@string/accessibility_service_label&quot;&gt;
+    &lt;intent-filter&gt;
+      &lt;action android:name=&quot;android.accessibilityservice.AccessibilityService&quot; /&gt;
+    &lt;/intent-filter&gt;
+  &lt;/service&gt;
+&lt;/application&gt;
+</pre>
+
+<p>These declarations are required for all accessibility services deployed on Android 1.6 (API Level
+ 4) or higher.</p>
+
+
+<h3 id="service-config">Accessibility service configuration</h3>
+
+<p>Accessibility services must also provide a configuration which specifies the types of
+accessibility events that the service handles and additional information about the service. The
+configuration of an accessibility service is contained in the {@link
+android.accessibilityservice.AccessibilityServiceInfo} class. Your service can build and set a
+configuration using an instance of this class and {@link
+android.accessibilityservice.AccessibilityService#setServiceInfo setServiceInfo()} at runtime.
+However, not all configuration options are available using this method.</p>
+
+<p>Beginning with Android 4.0, you can include a {@code &lt;meta-data&gt;} element in your manifest
+with a reference to a configuration file, which allows you to set the full range of options for
+your accessibility service, as shown in the following example:</p>
+
+<pre>
+&lt;service android:name=&quot;.MyAccessibilityService&quot;&gt;
+  ...
+  &lt;meta-data
+    android:name=&quot;android.accessibilityservice&quot;
+    android:resource=&quot;@xml/accessibility_service_config&quot; /&gt;
+&lt;/service&gt;
+</pre>
+
+<p>This meta-data element refers to an XML file that you create in your application’s resource
+directory ({@code &lt;project_dir&gt;/res/xml/accessibility_service_config.xml}). The following code
+shows example contents for the service configuration file:</p>
+
+<pre>
+&lt;accessibility-service xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+    android:description=&quot;@string/accessibility_service_description&quot;
+    android:packageNames=&quot;com.example.android.apis&quot;
+    android:accessibilityEventTypes=&quot;typeAllMask&quot;
+    android:accessibilityFlags=&quot;flagDefault&quot;
+    android:accessibilityFeedbackType=&quot;feedbackSpoken&quot;
+    android:notificationTimeout=&quot;100&quot;
+    android:canRetrieveWindowContent=&quot;true&quot;
+    android:settingsActivity=&quot;com.example.android.accessibility.ServiceSettingsActivity&quot;
+/&gt;
+</pre>
+
+<p>One of the most important functions of the accessibility service configuration parameters is to
+allow you to specify what types of accessibility events your service can handle. Being able to
+specify this information enables accessibility services to cooperate with each other, and allows you
+as a developer the flexibility to handle only specific events types from specific applications. The
+event filtering can include the following criteria:</p>
+
+<ul>
+  <li><strong>Package Names</strong> - Specify the package names of applications whose accessibility
+events you want your service to handle. If this parameter is omitted, your accessibility service is
+considered available to service accessibility events for any application. This parameter can be set
+in the accessibility service configuration files with the {@code android:packageNames} attribute as
+a comma-separated list, or set using the {@link
+android.accessibilityservice.AccessibilityServiceInfo#packageNames
+AccessibilityServiceInfo.packageNames} member.</li>
+  <li><strong>Event Types</strong> - Specify the types of accessibility events you want your service
+to handle. This parameter can be set in the accessibility service configuration files with the
+{@code android:accessibilityEventTypes} attribute as a comma-separated list, or set using the
+{@link android.accessibilityservice.AccessibilityServiceInfo#eventTypes
+AccessibilityServiceInfo.eventTypes} member. </li>
+</ul>
+
+<p>For more information about the XML attributes which can be used in the accessibility service
+ configuration file, follow these links to the reference documentation:</p>
+
+<ul>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_description">{@code android:description}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_packageNames">{@code android:packageNames}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityEventTypes">{@code android:accessibilityEventTypes}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityFlags">{@code android:accessibilityFlags}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityFeedbackType">{@code android:accessibilityFeedbackType}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_notificationTimeout">{@code android:notificationTimeout}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_canRetrieveWindowContent">{@code android:canRetrieveWindowContent}</a></li>
+  <li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_settingsActivity">{@code android:settingsActivity}</a></li>
+</ul>
+
+<p>For more information about which configuration settings can be dynamically set at runtime, see
+the {@link android.accessibilityservice.AccessibilityServiceInfo} reference documentation.</p>
+
+
+<h2 id="methods">AccessibilityService Methods</h2>
+
+<p>An application that provides accessibility service must extend the {@link
+android.accessibilityservice.AccessibilityService} class and override the following methods from
+that class. These methods are presented in the order in which they are called by the Android system,
+from when the service is started
+({@link android.accessibilityservice.AccessibilityService#onServiceConnected onServiceConnected()}),
+while it is running ({@link android.accessibilityservice.AccessibilityService#onAccessibilityEvent
+onAccessibilityEvent()},
+{@link android.accessibilityservice.AccessibilityService#onInterrupt onInterrupt()}) to when it is
+shut down ({@link android.accessibilityservice.AccessibilityService#onUnbind onUnbind()}).</p>
+
+<ul>
+  <li>{@link android.accessibilityservice.AccessibilityService#onServiceConnected
+onServiceConnected()} - (optional) This system calls this method when it successfully connects to
+your accessibility service. Use this method to do any one-time setup steps for your service,
+including connecting to user feedback system services, such as the audio manager or device vibrator.
+If you want to set the configuration of your service at runtime or make one-time adjustments, this
+is a convenient location from which to call {@link
+android.accessibilityservice.AccessibilityService#setServiceInfo setServiceInfo()}.</li>
+
+  <li>{@link android.accessibilityservice.AccessibilityService#onAccessibilityEvent
+onAccessibilityEvent()} - (required) This method is called back by the system when it detects an
+{@link android.view.accessibility.AccessibilityEvent} that matches the event filtering parameters
+specified by your accessibility service. For example, when the user clicks a button or focuses on a
+user interface control in an application for which your accessibility service is providing feedback.
+When this happens, the system calls this method of your service with the associated {@link
+android.view.accessibility.AccessibilityEvent}, which you can then interpret and provide feedback to
+the user. This method may be called many times over the lifecycle of your service.</li>
+
+  <li>{@link android.accessibilityservice.AccessibilityService#onInterrupt onInterrupt()} -
+(required) This method is called when the system wants to interrupt the feedback your service is
+providing, usually in response to a user taking action, such as moving focus to a different user
+interface control than the one for which you are currently providing feedback. This method may be
+called many times over the lifecycle of your service.</li>
+
+  <li>{@link android.accessibilityservice.AccessibilityService#onUnbind onUnbind()} - (optional)
+This method is called when the system is about to shutdown the accessibility service. Use this
+method to do any one-time shutdown procedures, including de-allocating user feedback system
+services, such as the audio manager or device vibrator.</li>
+</ul>
+
+<p>These callback methods provide the basic structure for your accessibility service. It is up to
+you to decide on how to process data provided by the Android system in the form of {@link
+android.view.accessibility.AccessibilityEvent} objects and provide feedback to the user.</p>
+
+
+<h2 id="event-details">Getting Event Details</h2>
+
+<p>The Android system provides information to accessibility services about the user interface
+interaction through {@link android.view.accessibility.AccessibilityEvent} objects. Prior to Android
+4.0, the information available in an accessibility event, while providing a significant amount of
+detail about a user interface control selected by the user, typically provided limited contextual
+information. In many cases, this missing context information might be critical to understanding the
+meaning of the selected control.</p>
+
+<p>A typical example of an interface where context is of critical importance is a calendar or day
+planner. If a user selects a 4:00 PM time slot in a Monday to Friday day list and the accessibility
+service announces “4 PM”, but fails to indicate this is a Friday a Monday, the month or day, this is
+hardly ideal feedback for the user. In this case, the context of a user interface control is of
+critical importance to a user who wants to schedule a meeting.</p>
+
+<p>Android 4.0 significantly extends the amount of information that an accessibility service can
+obtain about an user interface interaction by composing accessibility events based on the view
+hierarchy. A view hierarchy is the set of user interface components that contain the component (its
+parents) and the user interface elements that may be contained by that component (its children). In
+this way, the Android system can provide much richer detail about accessibility events, allowing
+accessibility services to provide more useful feedback to users.</p>
+
+<p>An accessibility service gets information about an user interface event through an {@link
+android.view.accessibility.AccessibilityEvent} passed by the system to the service’s
+{@link android.accessibilityservice.AccessibilityService#onAccessibilityEvent
+onAccessibilityEvent()} callback method. This object provides details about the event, including the
+type of object being acted upon, its descriptive text and other details. Starting in Android 4.0
+(and supported in previous releases through the {@link
+android.support.v4.view.accessibility.AccessibilityEventCompat} object in the Support Library), you
+can obtain additional information about the event using these calls:</p>
+
+<ul>
+  <li>{@link android.view.accessibility.AccessibilityEvent#getRecordCount
+AccessibilityEvent.getRecordCount()} and {@link
+android.view.accessibility.AccessibilityEvent#getRecord getRecord(int)} - These methods allow you to
+retrieve the set of {@link android.view.accessibility.AccessibilityRecord} objects which contributed
+to the {@link android.view.accessibility.AccessibilityEvent} passed to you by the system, which can
+provide more context for your accessibility service.</li>
+
+  <li>{@link android.view.accessibility.AccessibilityEvent#getSource
+AccessibilityEvent.getSource()} - This method returns an {@link
+android.view.accessibility.AccessibilityNodeInfo} object. This object allows you to request the
+parents and children of the component that originated the accessibility event and investigate their
+contents and state in order to provide
+
+    <p class="caution"><strong>Important:</strong> The ability to investigate the full view
+hierarchy from an {@link android.view.accessibility.AccessibilityEvent} potentially exposes private
+user information to your accessibility service. For this reason, your service must request this
+level of access through the accessibility <a href="#service-config">service configuration XML</a>
+file, by including the {@code canRetrieveWindowContent} attribute and setting it to {@code true}. If
+you do not include this setting in your service configuration xml file, calls to {@link
+android.view.accessibility.AccessibilityEvent#getSource getSource()} fail.</p>
+  </li>
+</ul>
+
+
+<h2 id="examples">Example Code</h2>
+
+<p>The API Demo project contains two samples which can be used as a starting point for generating
+accessibility services
+({@code &lt;sdk&gt;/samples/&lt;platform&gt;/ApiDemos/src/com/example/android/apis/accessibility}):
+</p>
+
+<ul>
+  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/accessibility/ClockBackService.html">ClockBackService</a>
+ - This service is based on the original implementation of {@link
+android.accessibilityservice.AccessibilityService} and can be used as a base for developing basic
+accessibility services that are compatible with Android 1.6 (API Level 4) and higher.</li>
+  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.html">TaskBackService</a>
+ - This service is based on the enhanced accessibility APIs introduced in Android 4.0 (API Level
+14). However, you can use the Android <a href="{@docRoot}sdk/compatibility-library.html">Support
+Libary</a> to substitute classes introduced in later API levels (e.g.,
+{@link android.view.accessibility.AccessibilityRecord},
+{@link android.view.accessibility.AccessibilityNodeInfo}
+) with equivalent support package classes (e.g.,
+{@link android.support.v4.view.accessibility.AccessibilityRecordCompat},
+{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}
+) to make this example work with API versions back to Android 1.6 (API Level 4).</li>
+</ul>
diff --git a/docs/html/images/training/cool-places.png b/docs/html/images/training/cool-places.png
new file mode 100755
index 0000000..769b5b7
--- /dev/null
+++ b/docs/html/images/training/cool-places.png
Binary files differ
diff --git a/docs/html/images/training/panoramio-grid.png b/docs/html/images/training/panoramio-grid.png
new file mode 100755
index 0000000..45c0eb5
--- /dev/null
+++ b/docs/html/images/training/panoramio-grid.png
Binary files differ
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 303a6d4..bbbe6fb1 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -100,8 +100,9 @@
       
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>training/efficient-downloads/index.html">
-            <span class="en">Transferring Data Without Draining the Battery</span>
-          </a> <span class="new">new!</span></div>
+            <span class="en">Transferring Data Without Draining the Battery<span
+class="new">&nbsp;new!</span></span>
+          </a></div>
         <ul>
           <li><a href="<?cs var:toroot ?>training/efficient-downloads/efficient-network-access.html">
             <span class="en">Optimizing Downloads for Efficient Network Access</span>
@@ -124,8 +125,8 @@
 
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>training/search/index.html">
-            <span class="en">Adding Search Functionality</span>
-          </a> <span class="new">new!</span>
+            <span class="en">Adding Search Functionality<span class="new">&nbsp;new!</span></span>
+          </a>
         </div>
         <ul>
           <li><a href="<?cs var:toroot ?>training/search/setup.html">
@@ -277,7 +278,44 @@
           </a>
           </li>
         </ul>
+       </li>
+       <li class="toggle-list">
+        <div><a href="<?cs var:toroot ?>training/tv/index.html">
+           <span class="en">Designing for TV<span class="new">&nbsp;new!</span></span>
+           </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/tv/optimizing-layouts-tv.html">
+            <span class="en">Optimizing Layouts for TV</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/tv/optimizing-navigation-tv.html">
+            <span class="en">Optimizing Navigation for TV</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/tv/unsupported-features-tv.html">
+            <span class="en">Handling Features Not Supported on TV</span>
+          </a>
+          </li>
+        </ul>
       </li>
+
+      <li class="toggle-list">
+        <div><a href="<?cs var:toroot ?>training/accessibility/index.html">
+            <span class="en">Implementing Accessibility<span class="new">&nbsp;new!</span></span>
+          </a></div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/accessibility/accessible-app.html">
+            <span class="en">Developing Accessible Applications</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/accessibility/service.html">
+            <span class="en">Developing Accessibility Services</span>
+          </a>
+          </li>
+        </ul>
+      </li>
+
     </ul>
   </li>    
       
diff --git a/docs/html/shareables/training/LocationAware.zip b/docs/html/shareables/training/LocationAware.zip
new file mode 100644
index 0000000..e1926fa
--- /dev/null
+++ b/docs/html/shareables/training/LocationAware.zip
Binary files differ
diff --git a/docs/html/training/accessibility/accessible-app.jd b/docs/html/training/accessibility/accessible-app.jd
new file mode 100644
index 0000000..f4087b8
--- /dev/null
+++ b/docs/html/training/accessibility/accessible-app.jd
@@ -0,0 +1,194 @@
+
+page.title=Developing Accessible Applications
+parent.title=Implementing Accessibility
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Developing an Accessibility Service
+next.link=service.html
+
+@jd:body
+
+
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#contentdesc">Add Content Descriptions</a></li>
+  <li><a href="#focus">Design for Focus Navigation</a></li>
+  <li><a href="#events">Fire Accessibility Events</a></li>
+  <li><a href="#testing">Test Your Application</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making
+    Applications Accessible</a></li>
+</ul>
+
+
+</div>
+</div>
+
+<p>Android has several accessibility-focused features baked into the platform,
+which make it easy to optimize your application for those with visual or
+physical disabilities.  However, it's not always obvious what the correct
+optimizations are, or the easiest way to leverage the framework toward this
+purpose.  This lesson shows you how to implement the strategies and platform
+features that make for a great accessibility-enabled Android application.</p>
+
+<h2 id="contentdesc">Add Content Descriptions</h2>
+<p>A well-designed user interface (UI) often has elements that don't require an explicit
+label to indicate their purpose to the user.  A checkbox next to an item in a
+task list application has a fairly obvious purpose, as does a trash can in a file
+manager application.  However, to your users with vision impairment, other UI
+cues are needed.</p>
+
+<p>Fortunately, it's easy to add labels to UI elements in your application that
+can be read out loud to your user by a speech-based accessibility service like <a
+  href="https://market.android.com/details?id=com.google.android.marvin.talkback">TalkBack</a>.
+If you have a label that's likely not to change during the lifecycle of the
+application (such as "Pause" or "Purchase"), you can add it via the XML layout,
+by setting a UI element's <a
+  href="{@docRoot}reference/android/view.View#attr_android:contentDescription">android:contentDescription</a> attribute, like in this
+example:</p>
+<pre>
+&lt;Button
+    android:id=”@+id/pause_button”
+    android:src=”@drawable/pause”
+    android:contentDescription=”@string/pause”/&gt;
+</pre>
+
+<p>However, there are plenty of situations where it's desirable to base the content
+description on some context, such as the state of a toggle button, or a piece
+selectable data like a list item.  To edit the content description at runtime,
+use the {@link android.view.View#setContentDescription(CharSequence)
+setContentDescription()} method, like this:</p>
+
+<pre>
+String contentDescription = "Select " + strValues[position];
+label.setContentDescription(contentDescription);
+</pre>
+
+<p>This addition to your code is the simplest accessibility improvement you can make to your
+application, but one of the most useful.  Try to add content descriptions
+wherever there's useful information, but avoid the web-developer pitfall of
+labelling <em>everything</em> with useless information.  For instance, don't set
+an application icon's content description to "app icon".  That just increases
+the noise a user needs to navigate in order to pull useful information from your
+interface.</p>
+
+<p>Try it out!  Download <a
+  href="https://market.android.com/details?id=com.google.android.marvin.talkback">TalkBack</a>
+(an accessibility service published by Google) and enable it in <strong>Settings
+  &gt; Accessibility &gt; TalkBack</strong>.  Then navigate around your own
+application and listen for the audible cues provided by TalkBack.</p>
+
+<h2 id="focus">Design for Focus Navigation</h2>
+<p>Your application should support more methods of navigation than the
+touch screen alone.  Many Android devices come with navigation hardware other
+than the touchscreen, like a D-Pad, arrow keys, or a trackball.  In addition,
+later Android releases also support connecting external devices like keyboards
+via USB or bluetooth.</p>
+
+<p>In order to enable this form of navigation, all navigational elements that
+the user should be able to navigate to need to be set as focusable.  This
+modification can be
+done at runtime using the
+{@link android.view.View#setFocusable View.setFocusable()} method on that UI
+control, or by setting the <a
+  href="{@docRoot}android.view.View#attr_android:focusable">{@code
+  android:focusable}</a>
+attrubute in your XML layout files.</p>
+
+<p>Also, each UI control has 4 attributes,
+<a href="{@docRoot}reference/android/view/View#attr_android:nextFocusUp">{@code
+  android:nextFocusUp}</a>,
+<a
+  href="{@docRoot}reference/android/view/View#attr_android:nextFocusDown">{@code
+  android:nextFocusDown}</a>,
+<a
+  href="{@docRoot}reference/android/view/View#attr_android:nextFocusLeft">{@code
+  android:nextFocusLeft}</a>,
+and <a
+  href="{@docRoot}reference/android/view/View#attr_android:nextFocusRight">{@code
+  android:nextFocusRight}</a>,
+which you can use to designate
+the next view to receive focus when the user navigates in that direction.  While
+the platform determines navigation sequences automatically based on layout
+proximity, you can use these attributes to override that sequence if it isn't
+appropriate in your application. </p>
+
+<p>For instance, here's how you represent a button and label, both
+focusable, such that pressing down takes you from the button to the text view, and
+pressing up would take you back to the button.</p>
+
+
+<pre>
+&lt;Button android:id="@+id/doSomething"
+    android:focusable="true"
+    android:nextFocusDown=”@id/label”
+    ... /&gt;
+&lt;TextView android:id="@+id/label"
+    android:focusable=”true”
+    android:text="@string/labelText"
+    android:nextFocusUp=”@id/doSomething”
+    ... /&gt;
+</pre>
+
+<p>Verify that your application works intuitively in these situations.  The
+easiest way is to simply run your application in the Android emulator, and
+navigate around the UI with the emulator's arrow keys, using the OK button as a
+replacement for touch to select UI controls.</p>
+
+<h2 id="events">Fire Accessibility Events</h2>
+<p>If you're using the view components in the Android framework, an
+{@link android.view.accessibility.AccessibilityEvent} is created whenever you
+select an item or change focus in your UI.  These events are examined by the
+accessibility service, enabling it to provide features like text-to-speech to
+the user.</p>
+
+<p>If you write a custom view, make sure it fires events at the appropriate
+times. Generate events by calling {@link
+android.view.View#sendAccessibilityEvent(int)}, with a parameter representing
+the type of event that occurred.  A complete list of the event types currently
+supported can be found in the {@link
+android.view.accessibility.AccessibilityEvent} reference documentation.
+
+<p>As an example, if you want to extend an image view such that you can write
+captions by typing on the keyboard when it has focus, it makes sense to fire an 
+{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
+event, even though that's not normally built into image views.  The code to
+generate that event would look like this:</p>
+<pre>
+public void onTextChanged(String before, String after) {
+    ...
+    if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+    }
+    ...
+}
+</pre>
+
+<h2 id="testing">Test Your Application</h2>
+<p>Be sure to test the accessibility functionality as you add it to your
+application.  In order to test the content descriptions and Accessibility
+events, install and enable an accessibility service.  One option is <a
+  href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">Talkback</a>,
+a free, open source screen reader available on Google Play.  With the service
+enabled, test all the navigation flows through your application and listen to
+the spoken feedback.</p>
+
+<p>Also, attempt to navigate your application using a directional controller,
+instead of the touch screen.  You can use a physical device with a d-pad or
+trackball if one is available.  If not, use the Android emulator and it's
+simulated keyboard controls.</p>
+
+<p>Between the service providing feedback and the directional navigation through
+your application, you should get a sense of what your application is like to
+navigate without any visual cues.  Fix problem areas as they appear, and you'll
+end up with with a more accessible Android application.</p>
diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd
new file mode 100644
index 0000000..d5178a9
--- /dev/null
+++ b/docs/html/training/accessibility/index.jd
@@ -0,0 +1,56 @@
+page.title=Implementing Accessibility
+
+trainingnavtop=true
+startpage=true
+next.title=Developing Accessible Applications
+next.link=accessible-app.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+  <li>Android 2.0 (API Level 5) or higher</li>
+Playback</a></li>
+</ul>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>When it comes to reaching as wide a userbase as possible, it's important to
+pay attention to accessibility in your Android application.  Cues in your user
+interface that may work for a majority of users, such as a visible change in
+state when a button is pressed, can be less optimal if the user is visually
+impaired.</p>
+
+<p>This class shows you how to make the most of the accessibility features
+built into the Android framework.  It covers how to optimize your app for
+accessibility, leveraging platform features like focus navigation and content
+descriptions.  It also covers how to build accessibility services, that can
+facilitate user interaction with <strong>any</strong> Android application, not
+just your own.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+  <dt><b><a href="accessible-app.html">Developing Accessible Applications</a></b></dt>
+    <dd>Learn to make your Android application accessible.  Allow for easy
+    navigation with a keyboard or directional pad, set labels and fire events
+    that can be interpreted by an accessibility service to facilitate a smooth
+    user experience.</dd>
+
+  <dt><b><a href="service.html">Developing Accessibility Services</a></b></dt>
+    <dd>Develop an accessibility service that listens for accessibility events,
+    mines those events for information like event type and content descriptions,
+    and uses that information to communicate with the user.  The example will
+    use a text-to-speech engine to speak to the user.</dd>
+
+</dl>
+
diff --git a/docs/html/training/accessibility/service.jd b/docs/html/training/accessibility/service.jd
new file mode 100644
index 0000000..f62506b
--- /dev/null
+++ b/docs/html/training/accessibility/service.jd
@@ -0,0 +1,286 @@
+
+page.title=Developing an Accessibility Service
+parent.title=Implementing Accessibility
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Developing Accessible Applications
+previous.link=accessible-app.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#create">Create Your Accessibility Service</a></li>
+  <li><a href="#configure">Configure Your Accessibility Service</a></li>
+  <li><a href="#events">Respond to AccessibilityEvents</a></li>
+  <li><a href="#query">Query the View Heirarchy for More Context</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/accessibility/services.html">Building
+  Accessibility Services</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>Accessibility services are a feature of the Android framework designed to
+provide alternative navigation feedback to the user on behalf of applications
+installed on Android devices.  An accessibility service can communicate to the
+user on the application's behalf, such as converting text to speech, or haptic
+feedback when a user is hovering on an important area of the screen.  This
+lesson covers how to create an accessibility service, process information
+received from the application, and report that information back to the
+user.</p>
+
+
+<h2 id="create">Create Your Accessibility Service</h2>
+<p>An accessibility service can be bundled with a normal application, or created
+as a standalone Android project.  The steps to creating the service are the same
+in either situation.  Within your project, create a class that extends {@link
+android.accessibilityservice.AccessibilityService}.</p>
+
+<pre>
+package com.example.android.apis.accessibility;
+
+import android.accessibilityservice.AccessibilityService;
+
+public class MyAccessibilityService extends AccessibilityService {
+...
+    &#64;Override
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+    }
+
+    &#64;Override
+    public void onInterrupt() {
+    }
+
+...
+}
+</pre>
+
+<p>Like any other service, you also declare it in the manifest file.
+Remember to specify that it handles the {@code android.accessibilityservice} intent,
+so that the service is called when applications fire an 
+{@link android.view.accessibility.AccessibilityEvent}.</p>
+
+<pre>
+&lt;application ...&gt;
+...
+&lt;service android:name=".MyAccessibilityService"&gt;
+     &lt;intent-filter&gt;
+         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
+     &lt;/intent-filter&gt;
+     . . .
+&lt;/service&gt;
+...
+&lt;/application&gt;
+</pre>
+
+<p>If you created a new project for this service, and don't plan on having an
+application, you can remove the starter Activity class (usually called MainActivity.java) from your source.  Remember to
+also remove the corresponding activity element from your manifest.</p>
+
+<h2 id="configure">Configure Your Accessibility Service</h2>
+<p>Setting the configuration variables for your accessibility service tells the
+system how and when you want it to run.  Which event types would you like to
+respond to?  Should the service be active for all applications, or only specific
+package names?  What different feedback types does it use?</p>
+
+<p>You have two options for how to set these variables.  The
+backwards-compatible option is to set them in code, using {@link
+android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}.
+To do that, override the {@link
+android.accessibilityservice.AccessibilityService#onServiceConnected()} method
+and configure your service in there.</p>
+
+<pre>
+&#64;Override
+public void onServiceConnected() {
+    // Set the type of events that this service wants to listen to.  Others
+    // won't be passed to this service.
+    info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
+            AccessibilityEvent.TYPE_VIEW_FOCUSED;
+
+    // If you only want this service to work with specific applications, set their
+    // package names here.  Otherwise, when the service is activated, it will listen
+    // to events from all applications.
+    info.packageNames = new String[]
+            {"com.example.android.myFirstApp", "com.example.android.mySecondApp"};
+
+    // Set the type of feedback your service will provide.
+    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
+
+    // Default services are invoked only if no package-specific ones are present
+    // for the type of AccessibilityEvent generated.  This service *is*
+    // application-specific, so the flag isn't necessary.  If this was a
+    // general-purpose service, it would be worth considering setting the
+    // DEFAULT flag.
+
+    // info.flags = AccessibilityServiceInfo.DEFAULT;
+
+    info.notificationTimeout = 100;
+
+    this.setServiceInfo(info);
+
+}
+</pre>
+
+<p>Starting with Android 4.0, there is a second option available: configure the
+service using an XML file.  Certain configuration options like
+{@link android.R.attr#canRetrieveWindowContent} are only available if you
+configure your service using XML.  The same configuration options above, defined
+using XML, would look like this:</p>
+
+<pre>
+&lt;accessibility-service
+     android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
+     android:packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp"
+     android:accessibilityFeedbackType="feedbackSpoken"
+     android:notificationTimeout="100"
+     android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity"
+     android:canRetrieveWindowContent="true"
+/&gt;
+</pre>
+
+<p>If you go the XML route, be sure to reference it in your manifest, by adding
+a <a
+href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a> tag to
+your service declaration, pointing at the XML file.  If you stored your XML file
+in {@code res/xml/serviceconfig.xml}, the new tag would look like this:</p>
+
+<pre>
+&lt;service android:name=".MyAccessibilityService"&gt;
+     &lt;intent-filter&gt;
+         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
+     &lt;/intent-filter&gt;
+     &lt;meta-data android:name="android.accessibilityservice"
+     android:resource="@xml/serviceconfig" /&gt;
+&lt;/service&gt;
+</pre>
+
+<h2 id="events">Respond to AccessibilityEvents</h2>
+<p>Now that your service is set up to run and listen for events, write some code
+so it knows what to do when an {@link
+android.view.accessibility.AccessibilityEvent} actually arrives!  Start by
+overriding the {@link
+android.accessibilityservice.AccessibilityService#onAccessibilityEvent} method.
+In that method, use {@link
+android.view.accessibility.AccessibilityEvent#getEventType} to determine the
+type of event, and {@link
+android.view.accessibility.AccessibilityEvent#getContentDescription} to extract
+any label text associated with the fiew that fired the event.</pre>
+
+<pre>
+&#64;Override
+public void onAccessibilityEvent(AccessibilityEvent event) {
+    final int eventType = event.getEventType();
+    String eventText = null;
+    switch(eventType) {
+        case AccessibilityEvent.TYPE_VIEW_CLICKED:
+            eventText = "Focused: ";
+            break;
+        case AccessibilityEvent.TYPE_VIEW_FOCUSED:
+            eventText = "Focused: ";
+            break;
+    }
+
+    eventText = eventText + event.getContentDescription();
+
+    // Do something nifty with this text, like speak the composed string
+    // back to the user.
+    speakToUser(eventText);
+    ...
+}
+</pre>
+
+<h2 id="query">Query the View Heirarchy for More Context</h2>
+<p>This step is optional, but highly useful.  One of the new features in Android
+4.0 (API Level 14) is the ability for an
+{@link android.accessibilityservice.AccessibilityService} to query the view
+hierarchy, collecting information about the the UI component that generated an event, and
+its parent and children.  In order to do this, make sure that you set the
+following line in your XML configuration:</p>
+<pre>
+android:canRetrieveWindowContent="true"
+</pre>
+<p>Once that's done, get an {@link
+android.view.accessibility.AccessibilityNodeInfo} object using {@link
+android.view.accessibility.AccessibilityEvent#getSource}.  This call only
+returns an object if the window where the event originated is still the active
+window.  If not, it will return null, so <em>behave accordingly</em>.  The
+following example is a snippet of code that, when it receives an event, does
+the following:
+<ol>
+  <li>Immediately grab the parent of the view where the event originated</li>
+  <li>In that view, look for a label and a check box as children views</li>
+  <li>If it finds them, create a string to report to the user, indicating
+  the label and whether it was checked or not.</li>
+  <li>If at any point a null value is returned while traversing the view
+  hierarchy, the method quietly gives up.</li>
+</ol>
+
+<pre>
+
+// Alternative onAccessibilityEvent, that uses AccessibilityNodeInfo
+
+&#64;Override
+public void onAccessibilityEvent(AccessibilityEvent event) {
+
+    AccessibilityNodeInfo source = event.getSource();
+    if (source == null) {
+        return;
+    }
+
+    // Grab the parent of the view that fired the event.
+    AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
+    if (rowNode == null) {
+        return;
+    }
+
+    // Using this parent, get references to both child nodes, the label and the checkbox.
+    AccessibilityNodeInfo labelNode = rowNode.getChild(0);
+    if (labelNode == null) {
+        rowNode.recycle();
+        return;
+    }
+
+    AccessibilityNodeInfo completeNode = rowNode.getChild(1);
+    if (completeNode == null) {
+        rowNode.recycle();
+        return;
+    }
+
+    // Determine what the task is and whether or not it's complete, based on
+    // the text inside the label, and the state of the check-box.
+    if (rowNode.getChildCount() &lt; 2 || !rowNode.getChild(1).isCheckable()) {
+        rowNode.recycle();
+        return;
+    }
+
+    CharSequence taskLabel = labelNode.getText();
+    final boolean isComplete = completeNode.isChecked();
+    String completeStr = null;
+
+    if (isComplete) {
+        completeStr = getString(R.string.checked);
+    } else {
+        completeStr = getString(R.string.not_checked);
+    }
+    String reportStr = taskLabel + completeStr;
+    speakToUser(reportStr);
+}
+
+</pre>
+
+<p>Now you have a complete, functioning accessibility service.  Try configuring
+how it interacts with the user, by adding Android's <a
+  href="http://developer.android.com/resources/articles/tts.html">text-to-speech
+  engine</a>, or using a {@link android.os.Vibrator} to provide haptic
+feedback!</p>
diff --git a/docs/html/training/location/currentlocation.jd b/docs/html/training/location/currentlocation.jd
new file mode 100644
index 0000000..4692530
--- /dev/null
+++ b/docs/html/training/location/currentlocation.jd
@@ -0,0 +1,155 @@
+page.title=Obtaining the Current Location
+parent.title=Making Your App Location Aware
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Using the Location Manager
+previous.link=locationmanager.html
+next.title=Displaying the Location Address
+next.link=geocoding.html
+
+
+@jd:body
+
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="currentlocation.html#TaskSetupLocationListener">Set Up the Location Listener</a></li>
+  <li><a href="currentlocation.html#TaskHandleLocationUpdates">Handle Multiple Sources of Location Updates</a></li>
+  <li><a href="currentlocation.html#TaskGetLastKnownLocation">Use getLastKnownLocation() Wisely</a></li>
+  <li><a href="currentlocation.html#TaskTerminateUpdates">Terminate Location Updates</a></li>
+</ol>
+
+<h2>You should also read</h2>
+
+<ul>
+  <li><a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/LocationAware.zip" class="button">Download
+  the sample app</a>
+<p class="filename">LocationAware.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>After setting up your application to work with {@link android.location.LocationManager}, you can begin to obtain location updates.</p>
+
+<h2 id="TaskSetupLocationListener">Set Up the Location Listener</h2>
+
+<p>The {@link android.location.LocationManager} class exposes a number of methods for applications to receive location updates.  In its simplest form, you register an event listener, identify the location manager from which you'd like to receive location updates, and specify the minimum time and distance intervals at which to receive location updates.  The {@link android.location.LocationListener#onLocationChanged(android.location.Location) onLocationChanged()} callback will be invoked with the frequency that correlates with time and distance intervals.</p>
+
+<p>
+In the sample code snippet below, the location listener is set up to receive notifications at least every 10 seconds and if the device moves by more than 10 meters.  The other callback methods notify the application any status change coming from the location provider.
+</p>
+
+<pre>
+private final LocationListener listener = new LocationListener() {
+
+    &#064;Override
+    public void onLocationChanged(Location location) {
+        // A new location update is received.  Do something useful with it.  In this case,
+        // we're sending the update to a handler which then updates the UI with the new
+        // location.
+        Message.obtain(mHandler,
+                UPDATE_LATLNG,
+                location.getLatitude() + ", " +
+                location.getLongitude()).sendToTarget();
+
+            ...
+        }
+    ...
+};
+
+mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+        10000,          // 10-second interval.
+        10,             // 10 meters.
+        listener);
+</pre>
+
+<h2 id="TaskHandleLocationUpdates">Handle Multiple Sources of Location Updates</h2>
+
+<p>Generally speaking, a location provider with greater accuracy (GPS) requires a longer fix time than one with lower accuracy (network-based).  If you want to display location data as quickly as possible and update it as more accurate data becomes available, a common practice is to register a location listener with both GPS and network providers.  In the {@link android.location.LocationListener#onLocationChanged(android.location.Location) onLocationChanged()} callback, you'll receive location updates from multiple location providers that may have different timestamps and varying levels of accuracy.  You'll need to incorporate logic to disambiguate the location providers and discard updates that are stale and less accurate.  The code snippet below demonstrates a sample implementation of this logic.</p>
+
+<pre>
+private static final int TWO_MINUTES = 1000 * 60 * 2;
+
+/** Determines whether one Location reading is better than the current Location fix
+  * @param location  The new Location that you want to evaluate
+  * @param currentBestLocation  The current Location fix, to which you want to compare the new one
+  */
+protected boolean isBetterLocation(Location location, Location currentBestLocation) {
+    if (currentBestLocation == null) {
+        // A new location is always better than no location
+        return true;
+    }
+
+    // Check whether the new location fix is newer or older
+    long timeDelta = location.getTime() - currentBestLocation.getTime();
+    boolean isSignificantlyNewer = timeDelta &gt; TWO_MINUTES;
+    boolean isSignificantlyOlder = timeDelta &lt; -TWO_MINUTES;
+    boolean isNewer = timeDelta > 0;
+
+    // If it's been more than two minutes since the current location, use the new location
+    // because the user has likely moved
+    if (isSignificantlyNewer) {
+        return true;
+    // If the new location is more than two minutes older, it must be worse
+    } else if (isSignificantlyOlder) {
+        return false;
+    }
+
+    // Check whether the new location fix is more or less accurate
+    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
+    boolean isLessAccurate = accuracyDelta &gt; 0;
+    boolean isMoreAccurate = accuracyDelta &lt; 0;
+    boolean isSignificantlyLessAccurate = accuracyDelta &gt; 200;
+
+    // Check if the old and new location are from the same provider
+    boolean isFromSameProvider = isSameProvider(location.getProvider(),
+            currentBestLocation.getProvider());
+
+    // Determine location quality using a combination of timeliness and accuracy
+    if (isMoreAccurate) {
+        return true;
+    } else if (isNewer &amp;&amp; !isLessAccurate) {
+        return true;
+    } else if (isNewer &amp;&amp; !isSignificantlyLessAccurate &amp;&amp; isFromSameProvider) {
+        return true;
+    }
+    return false;
+}
+
+/** Checks whether two providers are the same */
+private boolean isSameProvider(String provider1, String provider2) {
+    if (provider1 == null) {
+      return provider2 == null;
+    }
+    return provider1.equals(provider2);
+}
+</pre>
+
+<h2 id="TaskGetLastKnownLocation">Use getLastKnownLocation() Wisely</h2>
+
+<p>The setup time for getting a reasonable location fix may not be acceptable for certain applications.  You should consider calling the {@link android.location.LocationManager#getLastKnownLocation(java.lang.String) getLastKnownLocation()} method which simply queries Android for the last location update previously received by any location providers.  Keep in mind that the returned location may be stale.  You should check the timestamp and accuracy of the returned location and decide whether it is useful for your application.  If you elect to discard the location update returned from {@link android.location.LocationManager#getLastKnownLocation(java.lang.String) getLastKnownLocation()} and wait for fresh updates from the location provider(s), you should consider displaying an appropriate message before location data is received.</p>
+
+<h2 id="TaskTerminateUpdates">Terminate Location Updates</h2>
+
+<p>When you are done with using location data, you should terminate location update to reduce unnecessary consumption of power and network bandwidth.  For example, if the user navigates away from an activity where location updates are displayed, you should stop location update by calling {@link android.location.LocationManager#removeUpdates(android.location.LocationListener) removeUpdates()} in {@link android.app.Activity#onStop()}.  ({@link android.app.Activity#onStop()} is called when the activity is no longer visible.  If you want to learn more about activity lifecycle, read up on the <a href="/training/basic-activity-lifecycle/stopping.html">Starting and Stopping an Activity</a> lesson.</p>
+
+<pre>
+protected void onStop() {
+    super.onStop();
+    mLocationManager.removeUpdates(listener);
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> For applications that need to continuously receive and process location updates like a near-real time mapping application, it is best to incorporate the location update logic in a background service and make use of the system notification bar to make the user aware that location data is being used.</p>
\ No newline at end of file
diff --git a/docs/html/training/location/geocoding.jd b/docs/html/training/location/geocoding.jd
new file mode 100644
index 0000000..6364976
--- /dev/null
+++ b/docs/html/training/location/geocoding.jd
@@ -0,0 +1,98 @@
+page.title=Displaying the Location Address
+parent.title=Making Your App Location Aware
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Obtaining the Current Location
+previous.link=currentlocation.html
+
+@jd:body
+
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="geocoding.html#TaskReverseGeocoding">Perform Reverse Geocoding</a></li>
+</ol>
+
+<h2>You should also read</h2>
+
+<ul>
+  <li><a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/LocationAware.zip" class="button">Download
+  the sample app</a>
+<p class="filename">LocationAware.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>As shown in previous lessons, location updates are received in the form of latitude and longitude coordinates.  While this format is useful for calculating distance or displaying a pushpin on a map, the decimal numbers make no sense to most end users.  If you need to display a location to user, it is much more preferable to display the address instead.</p>
+
+<h2 id="TaskReverseGeocoding">Perform Reverse Geocoding</h2>
+
+<p>Reverse-geocoding is the process of translating latitude longitude coordinates to a human-readable address.  The {@link android.location.Geocoder} API is available for this purpose.  Note that behind the scene, the API is dependent on a web service.  If such service is unavailable on the device, the API will throw a "Service not Available exception" or return an empty list of addresses.  A helper method called {@link android.location.Geocoder#isPresent()} was added in Android 2.3 (API level 9) to check for the existence of the service.</p>
+
+<p>The following code snippet demonstrates the use of the {@link android.location.Geocoder} API to perform reverse-geocoding.  Since the {@link android.location.Geocoder#getFromLocation(double, double, int) getFromLocation()} method is synchronous, you should not invoke it from the UI thread, hence an {@link android.os.AsyncTask} is used in the snippet.</p>
+
+<pre>
+private final LocationListener listener = new LocationListener() {
+
+    public void onLocationChanged(Location location) {
+        // Bypass reverse-geocoding if the Geocoder service is not available on the
+        // device. The isPresent() convenient method is only available on Gingerbread or above.
+        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.GINGERBREAD &amp;&amp; Geocoder.isPresent()) {
+            // Since the geocoding API is synchronous and may take a while.  You don't want to lock
+            // up the UI thread.  Invoking reverse geocoding in an AsyncTask.
+            (new ReverseGeocodingTask(this)).execute(new Location[] {location});
+        }
+    }
+    ...
+};
+
+// AsyncTask encapsulating the reverse-geocoding API.  Since the geocoder API is blocked,
+// we do not want to invoke it from the UI thread.
+private class ReverseGeocodingTask extends AsyncTask&lt;Location, Void, Void&gt; {
+    Context mContext;
+
+    public ReverseGeocodingTask(Context context) {
+        super();
+        mContext = context;
+    }
+
+    &#064;Override
+    protected Void doInBackground(Location... params) {
+        Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
+
+        Location loc = params[0];
+        List&lt;Address&gt; addresses = null;
+        try {
+            // Call the synchronous getFromLocation() method by passing in the lat/long values.
+            addresses = geocoder.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
+        } catch (IOException e) {
+            e.printStackTrace();
+            // Update UI field with the exception.
+            Message.obtain(mHandler, UPDATE_ADDRESS, e.toString()).sendToTarget();
+        }
+        if (addresses != null &amps;&amps; addresses.size() &gt; 0) {
+            Address address = addresses.get(0);
+            // Format the first line of address (if available), city, and country name.
+            String addressText = String.format("&#037;s, &#037;s, &#037;s",
+                    address.getMaxAddressLineIndex() &gt; 0 ? address.getAddressLine(0) : "",
+                    address.getLocality(),
+                    address.getCountryName());
+            // Update the UI via a message handler.
+            Message.obtain(mHandler, UPDATE_ADDRESS, addressText).sendToTarget();
+        }
+        return null;
+    }
+}
+</pre>
\ No newline at end of file
diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd
new file mode 100644
index 0000000..48cfbc3
--- /dev/null
+++ b/docs/html/training/location/index.jd
@@ -0,0 +1,51 @@
+page.title=Making Your App Location Aware
+
+trainingnavtop=true
+startpage=true
+next.title=Using the Location Manager
+next.link=locationmanager.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+
+<ul>
+  <li>Android 1.0 or higher (2.3+ for the sample app)</li>
+</ul>
+
+<h2>You should also read</h2>
+
+<ul>
+  <li><a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/LocationAware.zip" class="button">Download
+  the sample app</a>
+<p class="filename">LocationAware.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Users bring their mobile devices with them almost everywhere.  One of the unique features available to mobile applications is location awareness.  Knowing the location and using the information wisely can bring a more contextual experience to your users.</p>
+
+<p>This class teaches you how to incorporate location based services in your Android application.  You'll learn a number of methods to receive location updates and related best practices.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+  <dt><b><a href="locationmanager.html">Using the Location Manager</a></b></dt>
+    <dd>Learn how to set up your application before it can receive location updates in Android.</dd>
+
+  <dt><b><a href="currentlocation.html">Obtaining the Current Location</a></b></dt>
+    <dd>Learn how to work with underlying location technologies available on the platform to obtain current location.</dd>
+
+  <dt><b><a href="geocoding.html">Displaying a Location Address</a></b></dt>
+    <dd>Learn how to translate location coordinates into addresses that are readable to users.</dd>
+</dl>
diff --git a/docs/html/training/location/locationmanager.jd b/docs/html/training/location/locationmanager.jd
new file mode 100644
index 0000000..5da1205
--- /dev/null
+++ b/docs/html/training/location/locationmanager.jd
@@ -0,0 +1,90 @@
+page.title=Using the Location Manager
+parent.title=Making Your App Location Aware
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Obtaining the Current Location
+next.link=currentlocation.html
+
+@jd:body
+
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="locationmanager.html#TaskDeclarePermissions">Declare Proper Permissions in Android Manifest</a></li>
+  <li><a href="locationmanager.html#TaskGetLocationManagerRef">Get a Reference to LocationManager</a></li>
+  <li><a href="locationmanager.html#TaskPickLocationProvider">Pick a Location Provider</a></li>
+</ol>
+
+<h2>You should also read</h2>
+
+<ul>
+  <li><a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/LocationAware.zip" class="button">Download
+  the sample app</a>
+<p class="filename">LocationAware.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Before your application can begin receiving location updates, it needs to perform some simple steps to set up access.  In this lesson, you'll learn what these steps entail.</p>
+
+<h2 id="TaskDeclarePermissions">Declare Proper Permissions in Android Manifest</h2>
+
+<p>The first step of setting up location update access is to declare proper permissions in the manifest.  If permissions are missing, the application will get a {@link java.lang.SecurityException} at runtime.</p>
+
+<p>Depending on the {@link android.location.LocationManager} methods used, either {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} or {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission is needed.  For example, you need to declare the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} permission if your application uses a network-based location provider only.  The more accurate GPS requires the {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
+Note that declaring the {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission implies {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} already.</p>
+
+<p>Also, if a network-based location provider is used in the application, you'll need to declare the internet permission as well.</p>
+
+<pre>
+&lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /&gt;
+&lt;uses-permission android:name="android.permission.INTERNET" /&gt;
+</pre>
+
+<h2 id="TaskGetLocationManagerRef">Get a Reference to LocationManager</h2>
+
+<p>{@link android.location.LocationManager} is the main class through which your application can access location services on Android.  Similar to other system services, a reference can be obtained from calling the {@link android.content.Context#getSystemService(java.lang.String) getSystemService()} method.  If your application intends to receive location updates in the foreground (within an {@link android.app.Activity}), you should usually perform this step in the {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method.</p>
+
+<pre>
+LocationManager locationManager =
+        (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
+</pre>
+
+<h2 id="TaskPickLocationProvider">Pick a Location Provider</h2>
+
+<p>While not required, most modern Android-powered devices can receive location updates through multiple underlying technologies, which are abstracted to an application as {@link android.location.LocationProvider} objects.  Location providers may have different performance characteristics in terms of time-to-fix, accuracy, monetary cost, power consumption, and so on.  Generally, a location provider with a greater accuracy, like the GPS, requires a longer fix time than a less accurate one, such as a network-based location provider.</p>
+
+<p>Depending on your application's use case, you have to choose a specific location provider, or multiple providers, based on similar tradeoffs.  For example, a points of interest check-in application would require higher location accuracy than say, a retail store locator where a city level location fix would suffice.  The snippet below asks for a provider backed by the GPS.</p>
+
+<pre>
+LocationProvider provider =
+        locationManager.getProvider(LocationManager.GPS_PROVIDER);
+</pre>
+
+<p>Alternatively, you can provide some input criteria such as accuracy, power requirement, monetary cost, and so on, and let Android decide a closest match location provider.  The snippet below asks for a location provider with fine accuracy and no monetary cost.  Note that the criteria may not resolve to any providers, in which case a null will be returned.  Your application should be prepared to gracefully handle the situation.</p>
+
+<pre>
+// Retrieve a list of location providers that have fine accuracy, no monetary cost, etc
+Criteria criteria = new Criteria();
+criteria.setAccuracy(Criteria.ACCURACY_FINE);
+criteria.setCostAllowed(false);
+...
+String providerName = locManager.getBestProvider(criteria, true);
+
+// If no suitable provider is found, null is returned.
+if (providerName != null) {
+   ...
+}
+</pre>
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
new file mode 100644
index 0000000..ae13c4a
--- /dev/null
+++ b/docs/html/training/tv/index.jd
@@ -0,0 +1,52 @@
+page.title=Designing for TV
+
+trainingnavtop=true
+startpage=true
+next.title=Optimizing layouts for TV
+next.link=optimizing-layouts-tv.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+<ul>
+  <li>Android 2.0 (API Level 5) or higher</li>
+</ul>
+
+</div>
+</div>
+<p> 
+  Smart TVs powered by Android bring your favorite Android apps to the best screen in your house. 
+  Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how 
+  you can optimize your Android app for TVs, including how to build a layout that 
+  works great when the user is ten feet away and navigating with a remote control. 
+</p> 
+
+<h2>Lessons</h2> 
+ 
+<dl> 
+  <dt><b><a href="optimizing-layouts-tv.html">Optimizing Layouts for TV</a></b></dt>
+    <dd>Shows you how to optimize app layouts for TV screens, which have some unique characteristics such as:
+    <ul>
+      <li>permanent "landscape" mode</li>
+      <li>high-resolution displays</li>
+      <li>"10 foot UI" environment.</li>
+    </ul>
+    </dd>
+ 
+  <dt><b><a href="optimizing-navigation-tv.html">Optimizing Navigation for TV</a></b></dt>
+    <dd>Shows you how to design navigation for TVs, including: 
+    <ul>
+      <li>handling D-pad navigation</li>
+      <li>providing navigational feedback</li>
+      <li>providing easily-accessible controls on the screen.</li>
+    </ul>
+    </dd>
+
+  <dt><b><a href="unsupported-features-tv.html">Handling features not supported on TV</a></b></dt>
+    <dd>Lists the hardware features that are usually not available on TVs. This lesson also shows you how to 
+    provide alternatives for missing features or check for missing features and disable code at run time.</dd>
+</dl> 
\ No newline at end of file
diff --git a/docs/html/training/tv/optimizing-layouts-tv.jd b/docs/html/training/tv/optimizing-layouts-tv.jd
new file mode 100644
index 0000000..6eac6d3
--- /dev/null
+++ b/docs/html/training/tv/optimizing-layouts-tv.jd
@@ -0,0 +1,246 @@
+page.title=Optimizing Layouts for TV
+parent.title=Designing for TV
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Optimizing Navigation for TV
+next.link=optimizing-navigation-tv.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#DesignLandscapeLayouts">Design Landscape Layouts</a></li>
+  <li><a href="#MakeTextControlsEasyToSee">Make Text and Controls Easy to See</a></li>
+  <li><a href="#DesignForLargeScreens">Design for High-Density Large Screens</a></li>
+  <li><a href="#HandleLargeBitmaps">Handle Large Bitmaps in Your Application</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>
+When your application is running on a television set, you should assume that the user is sitting about 
+ten feet away from the screen. This user environment is referred to as the 
+<a href="http://en.wikipedia.org/wiki/10-foot_user_interface">10-foot UI</a>. To provide your 
+users with a usable and enjoyable experience, you should style and lay out your UI accordingly..
+</p>
+<p>
+This lesson shows you how to optimize layouts for TV by:
+</p>
+<ul>
+  <li>Providing appropriate layout resources for landscape mode.</li>
+  <li>Ensuring that text and controls are large enough to be visible from a distance.</li>
+  <li>Providing high resolution bitmaps and icons for HD TV screens.</li>
+</ul>
+
+<h2 id="DesignLandscapeLayouts">Design Landscape Layouts</h2> 
+
+<p>
+TV screens are always in landscape orientation. Follow these tips to build landscape layouts optimized for TV screens:
+</p> 
+<ul>
+  <li>Put on-screen navigational controls on the left or right side of the screen and save the 
+  vertical space for content.</li>
+  <li>Create UIs that are divided into sections, by using <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> 
+  and use view groups like {@link android.widget.GridView} instead 
+  of {@link android.widget.ListView} to make better use of the 
+  horizontal screen space.</li>
+  <li>Use view groups such as {@link android.widget.RelativeLayout} 
+  or {@link android.widget.LinearLayout} to arrange views. 
+  This allows the Android system to adjust the position of the views to the size, alignment, 
+  aspect ratio, and pixel density of the TV screen.</li>
+  <li>Add sufficient margins between layout controls to avoid a cluttered UI.</li>
+</ul> 
+ 
+<p>
+For example, the following layout is optimized for TV:
+</p>
+
+<img src="{@docRoot}images/training/panoramio-grid.png" />
+
+<p>
+In this layout, the controls are on the lefthand side. The UI is displayed within a 
+{@link android.widget.GridView}, which is well-suited to landscape orientation.
+In this layout both GridView and Fragment have the width and height set 
+dynamically, so they can adjust to the screen resolution. Controls are added to the left side Fragment programatically at runtime.
+The layout file for this UI is {@code res/layout-land-large/photogrid_tv.xml}.
+(This layout file is placed in {@code layout-land-large} because TVs have large screens with landscape orientation. For details refer to 
+<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.)</p>
+
+res/layout-land-large/photogrid_tv.xml
+<pre>
+&lt;RelativeLayout
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" &gt;
+
+    &lt;fragment
+        android:id="@+id/leftsidecontrols"
+        android:layout_width="0dip"
+        android:layout_marginLeft="5dip"
+        android:layout_height="match_parent" /&gt;
+
+    &lt;GridView        
+        android:id="@+id/gridview"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" /&gt;
+
+&lt;/RelativeLayout>
+</pre>
+
+<p>
+To set up action bar items on the left side of the screen, you can also include the <a
+href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarLibrary">
+Left navigation bar library</a> in your application to set up action items on the left side 
+of the screen, instead of creating a custom Fragment to add controls:
+</p>
+
+<pre>
+LeftNavBar bar = (LeftNavBarService.instance()).getLeftNavBar(this);
+</pre>
+
+<p>
+When you have an activity in which the content scrolls vertically, always use a left navigation bar; 
+otherwise, your users have to scroll to the top of the content to switch between the content view and 
+the ActionBar. Look at the  
+<a href="http://code.google.com/p/googletv-android-samples/source/browse/#git%2FLeftNavBarDemo">
+Left navigation bar sample app</a> to see how to simple it is to include the left navigation bar in your app.
+</p>
+
+<h2 id="MakeTextControlsEasyToSee">Make Text and Controls Easy to See</h2>
+<p>
+The text and controls in a TV application's UI should be easily visible and navigable from a distance.
+Follow these tips to make them easier to see from a distance :
+</p>
+
+<ul>
+  <li>Break text into small chunks that users can quickly scan.</li>
+  <li>Use light text on a dark background. This style is easier to read on a TV.</li>
+  <li>Avoid lightweight fonts or fonts that have both very narrow and very broad strokes. Use simple sans-serif 
+  fonts and use anti-aliasing to increase readability.</li>
+  <li>Use Android's standard font sizes:
+  <pre>
+  &lt;TextView
+        android:id="@+id/atext"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:singleLine="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"/&gt;
+  </pre></li>
+  <li>Ensure that all your view widgets are large enough to be clearly visible to someone sitting 10 feet away 
+  from the screen (this distance is greater for very large screens).  The best way to do this is to use 
+  layout-relative sizing rather than absolute sizing, and density-independent pixel units instead of absolute 
+  pixel units. For example, to set the width of a widget, use wrap_content instead of a pixel measurement, 
+  and to set the margin for a widget, use dip instead of px values.
+  </li>
+</ul>
+<p>
+
+</p>
+
+<h2 id="DesignForLargeScreens">Design for High-Density Large Screens</h2>
+
+<p>
+The common HDTV display resolutions are 720p, 1080i, and 1080p. Design your UI for 1080p, and then 
+allow the Android system to downscale your UI to 720p if necessary. In general, downscaling (removing pixels) 
+does not degrade the UI (Notice that the converse is not true; you should avoid upscaling because it degrades 
+UI quality).
+</p>
+
+<p>
+To get the best scaling results for images, provide them as <a href="{@docRoot}guide/developing/tools/draw9patch.html">
+9-patch image</a> elements if possible.
+If you provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or grainy. This 
+is not a good experience for the user. Instead, use high-quality images. 
+</p>
+
+<p>
+For more information on optimizing apps for large screens see <a href="{@docRoot}training/multiscreen/index.html">
+Designing for multiple screens</a>.
+</p>
+
+<h2 id="HandleLargeBitmaps">Design to Handle Large Bitmaps</h2>
+
+<p>
+The Android system has a limited amount of memory, so downloading and storing high-resolution images can often 
+cause out-of-memory errors in your app. To avoid this, follow these tips:
+</p>
+
+<ul>
+  <li>Load images only when they're displayed on the screen. For example, when displaying multiple images in 
+      a {@link android.widget.GridView} or 
+      {@link android.widget.Gallery}, only load an image when 
+      {@link android.widget.Adapter#getView(int, View, ViewGroup) getView()} 
+      is called on the View's {@link android.widget.Adapter}.
+  </li>
+  <li>Call {@link android.graphics.Bitmap#recycle()} on 
+      {@link android.graphics.Bitmap} views that are no longer needed.
+  </li>
+  <li>Use {@link java.lang.ref.WeakReference} for storing references 
+      to {@link android.graphics.Bitmap} objects in a in-memory 
+      <a href="{@link java.util.Collection}.</li>
+  <li>If you fetch images from the network, use {@link android.os.AsyncTask} 
+      to fetch them and store them on the SD card for faster access.
+      Never do network transactions on the application's UI thread.
+  </li>
+  <li>Scale down really large images to a more appropriate size as you download them; otherwise, downloading the image 
+  itself may cause an "Out of Memory" exception. Here is sample code that scales down images while downloading:
+  
+  <pre>
+  // Get the source image's dimensions
+  BitmapFactory.Options options = new BitmapFactory.Options();
+  // This does not download the actual image, just downloads headers.
+  options.inJustDecodeBounds = true; 
+  BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
+  // The actual width of the image.
+  int srcWidth = options.outWidth;  
+  // The actual height of the image.
+  int srcHeight = options.outHeight;  
+
+  // Only scale if the source is bigger than the width of the destination view.
+  if(desiredWidth > srcWidth)
+    desiredWidth = srcWidth;
+
+  // Calculate the correct inSampleSize/scale value. This helps reduce memory use. It should be a power of 2.
+  int inSampleSize = 1;
+  while(srcWidth / 2 > desiredWidth){
+    srcWidth /= 2;
+    srcHeight /= 2;
+    inSampleSize *= 2;
+  }
+
+  float desiredScale = (float) desiredWidth / srcWidth;
+
+  // Decode with inSampleSize
+  options.inJustDecodeBounds = false;
+  options.inDither = false;
+  options.inSampleSize = inSampleSize;
+  options.inScaled = false;
+  // Ensures the image stays as a 32-bit ARGB_8888 image.
+  // This preserves image quality.
+  options.inPreferredConfig = Bitmap.Config.ARGB_8888;  
+                                                	
+  Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);
+
+  // Resize
+  Matrix matrix = new Matrix();
+  matrix.postScale(desiredScale, desiredScale);
+  Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
+      sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
+  sampledSrcBitmap = null;
+
+  // Save
+  FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
+  scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
+  scaledBitmap = null;
+   </pre>
+  </li> </ul>
\ No newline at end of file
diff --git a/docs/html/training/tv/optimizing-navigation-tv.jd b/docs/html/training/tv/optimizing-navigation-tv.jd
new file mode 100644
index 0000000..8b5878e
--- /dev/null
+++ b/docs/html/training/tv/optimizing-navigation-tv.jd
@@ -0,0 +1,206 @@
+page.title=Optimizing Navigation for TV
+parent.title=Designing for TV
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Optimizing Layouts for TV
+previous.link=optimizing-layouts-tv.html
+next.title=Handling features not supported on TV
+next.link=unsupported-features-tv.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#HandleDpadNavigation">Handle D-pad Navigation</a></li>
+  <li><a href="#HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</a></li>
+  <li><a href="#DesignForEasyNavigation">Design for Easy Navigation</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>
+An important aspect of the user experience when operating a TV is the direct human interface: a remote control. 
+As you optimize your Android application for TVs, you should pay special attention to how the user actually navigates 
+around your application when using a remote control instead of a touchscreen.
+</p>
+<p>
+This lesson shows you how to optimize navigation for TV by:
+</p>
+
+<ul>
+  <li>Ensuring all layout controls are D-pad navigable.</li>
+  <li>Providing highly obvious feedback for UI navigation.</li>
+  <li>Placing layout controls for easy access.</li>
+</ul>
+
+<h2 id="HandleDpadNavigation">Handle D-pad Navigation</h2> 
+
+<p>
+On a TV, users navigate with controls on a TV remote, using either a D-pad or arrow keys. 
+This limits movement to up, down, left, and right. 
+To build a great TV-optimized app, you must provide a navigation scheme in which the user can 
+quickly learn how to navigate your app using the remote.
+</p>
+
+<p>
+When you design navigation for D-pad, follow these guidelines:
+</p>
+
+<ul>
+  <li>Ensure that the D-pad  can navigate to all the visible controls on the screen.</li>
+  <li>For scrolling lists with focus, D-pad up/down keys scroll the list and Enter key selects an item in the list. Ensure that users can 
+  select an element in the list and that the list still scrolls when an element is selected.</li> 
+  <li>Ensure that movement between controls is straightforward and predictable.</li>
+</ul>
+
+<p>
+Android usually handles navigation order between layout elements automatically, so you don't need to do anything extra. If the screen layout 
+makes navigation difficult, or if you want users to move through the layout in a specific way, you can set up explicit navigation for your 
+controls.  
+For example, for an {@code android.widget.EditText}, to define the next control to receive focus, use:
+<pre>
+&lt;EditText android:id="@+id/LastNameField" android:nextFocusDown="@+id/FirstNameField"\&gt;
+</pre>
+The following table lists all of the available navigation attributes:
+</p>
+
+<table>
+<tr>
+<th>Attribute</th>
+<th>Function</th>
+</tr>
+<tr>
+<td>{@link android.R.attr#nextFocusDown}</td>
+<td>Defines the next view to receive focus when the user navigates down.</td>
+</tr>
+<tr>
+<td>{@link android.R.attr#nextFocusLeft}</td>
+<td>Defines the next view to receive focus when the user navigates left.</td>
+</tr>
+<tr>
+<td>{@link android.R.attr#nextFocusRight}</td>
+<td>Defines the next view to receive focus when the user navigates right.</td>
+</tr>
+<tr>
+<td>{@link android.R.attr#nextFocusUp}</td>
+<td>Defines the next view to receive focus when the user navigates up.</td>
+</tr>
+</table>
+
+<p>
+To use one of these explicit navigation attributes, set the value to the ID (android:id value) of another widget in the layout. You should set 
+up the navigation order as a loop, so that the last control directs focus back to the first one.
+</p>
+
+<p>
+Note: You should only use these attributes to modify the navigation order if the default order that the system applies does not work well.
+</p>
+
+<h2 id="HandleFocusSelection">Provide Clear Visual Indication for Focus and Selection</h2>
+
+<p>
+Use appropriate color highlights for all navigable and selectable elements in the UI. This makes it easy for users to know whether the control 
+is currently focused or selected when they navigate with a D-pad. Also, use uniform highlight scheme across your application.
+</p>
+
+<p>
+Android provides <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">Drawable State List Resources</a> to implement highlights 
+for selected and focused controls. For example:
+</p>
+
+res/drawable/button.xml:
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+    &lt;item android:state_pressed="true"
+          android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
+    &lt;item android:state_focused="true"
+          android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
+    &lt;item android:state_hovered="true"
+          android:drawable="@drawable/button_focused" /&gt; &lt;!-- hovered --&gt;
+    &lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
+&lt;/selector&gt;
+</pre>
+
+<p>
+This layout XML applies the above state list drawable to a {@link android.widget.Button}:
+</p>
+<pre>
+&lt;Button
+    android:layout_height="wrap_content"
+    android:layout_width="wrap_content"
+    android:background="@drawable/button" /&gt;
+</pre>
+
+<p>
+Provide sufficient padding within the focusable and selectable controls so that the highlights around them are clearly visible. 
+</p>
+
+<h2 id="DesignForEasyNavigation">Design for Easy Navigation</h2>
+
+<p>
+Users should be able to navigate to any UI control with a couple of D-pad clicks. Navigation should be easy and  intuitive to 
+understand.  For any non-intuitive actions, provide users with written help, using a dialog triggered by a help button or action bar icon. 
+</p>
+
+<p>
+Predict the next screen that the user will want to navigate to and provide one click navigation to it. If the current screen UI is very sparse, 
+consider making it a multi pane screen. Use fragments for making multi-pane screens. For example, consider the multi-pane UI below with continent names 
+on the left and list of cool places in each continent on the right. 
+</p>
+
+<img src="{@docRoot}images/training/cool-places.png" alt="" />
+
+<p>
+The above UI consists of three Fragments - <code>left_side_action_controls</code>, <code>continents</code> and 
+<code>places</code> - as shown in its layout 
+xml file below. Such multi-pane UIs make D-pad navigation easier and make good use of the horizontal screen space for 
+TVs.
+</p>
+res/layout/cool_places.xml
+<pre>
+&lt;LinearLayout   
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+   &gt;
+   &lt;fragment
+        android:id="@+id/left_side_action_controls"
+        android:layout_width="0px"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="10dip"
+        android:layout_weight="0.2"/&gt;
+    &lt;fragment
+        android:id="@+id/continents"
+        android:layout_width="0px"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="10dip"
+        android:layout_weight="0.2"/&gt;
+
+    &lt;fragment
+        android:id="@+id/places"
+        android:layout_width="0px"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="10dip"
+        android:layout_weight="0.6"/&gt;
+
+&lt;/LinearLayout&gt;
+</pre>
+
+<p>
+Also, notice in the UI layout above action controls are on the left hand side of a vertically scrolling list to make 
+them easily accessible using D-pad. 
+In general, for layouts with horizontally scrolling components, place action controls on left or right hand side and 
+vice versa for vertically scrolling components.
+</p>
+
diff --git a/docs/html/training/tv/unsupported-features-tv.jd b/docs/html/training/tv/unsupported-features-tv.jd
new file mode 100644
index 0000000..6b0f8c8
--- /dev/null
+++ b/docs/html/training/tv/unsupported-features-tv.jd
@@ -0,0 +1,156 @@
+page.title=Handling Features Not Supported on TV
+parent.title=Designing for TV
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Optimizing Navigation for TV
+previous.link=optimizing-navigation-tv.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</a></li>
+  <li><a href="#CheckAvailableFeatures">Check for Available Features at Runtime</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>
+TVs are much different from other Android-powered devices:
+</p>
+<ul>
+  <li>They're not mobile.</li>
+  <li>Out of habit, people use them for watching media with little or no interaction.</li>
+  <li>People interact with them from a distance.</li>
+</ul>
+
+<p>
+Because TVs have a different purpose from other devices, they usually don't have hardware features 
+that other Android-powered devices often have. For this reason, the Android system does not 
+support the following features for a TV device:
+<table>
+<tr>
+<th>Hardware</th>
+<th>Android feature descriptor</th>
+</tr>
+<tr>
+<td>Camera</td>
+<td>android.hardware.camera</td>
+</tr>
+<tr>
+<td>GPS</td>
+<td>android.hardware.location.gps</td>
+</tr>
+<tr>
+<td>Microphone</td>
+<td>android.hardware.microphone</td>
+</tr>
+<tr>
+<td>Near Field Communications (NFC)</td>
+<td>android.hardware.nfc</td>
+</tr>
+<tr>
+<td>Telephony</td>
+<td>android.hardware.telephony</td>
+</tr>
+<tr>
+<td>Touchscreen</td>
+<td>android.hardware.touchscreen</td>
+</tr>
+</table>
+</p>
+
+<p>
+This lesson shows you how to work around features that are not available on TV by:
+<ul>
+  <li>Providing work arounds for some non-supported features.</li>
+  <li>Checking for available features at runtime and conditionally activating/deactivating certain code 
+  paths based on availability of those features.</li>
+</ul>
+</p>
+
+
+<h2 id="WorkaroundUnsupportedFeatures">Work Around Features Not Supported on TV</h2> 
+
+<p>
+Android doesn't support touchscreen interaction for TV devices, most TVs don't have touch screens, 
+and interacting with a TV using a touchscreen is not consistent with the 10 foot environment. For 
+these reasons, users interact with Android-powered TVs using a remote. In consideration of this, 
+ensure that every control in your app can be accessed with the D-pad. Refer back to the previous two lessons 
+<a href="{@docRoot}training/tv/optimizing-layouts-tv">Optimizing Layouts for TV</a> and 
+<a href="{@docRoot}training/tv/optimizing-navigation-tv">Optimize Navigation for TV</a> for more details 
+on this topic. The Android system assumes that a device has a touchscreen, so if you want your application 
+to run on a TV, you must <strong>explicitly</strong> disable the touchscreen requirement in your manifest file:
+<pre>
+&lt;uses-feature android:name="android.hardware.touchscreen" android:required="false"/&gt;
+</pre>
+</p> 
+
+<p>
+Although a TV doesn't have a camera, you can still provide a photography-related application on a TV. 
+For example, if you have an app that takes, views and edits photos, you can disable its picture-taking 
+functionality for TVs and still allow users to view and even edit photos. The next section talks about how to 
+deactivate or activate specific functions in the application based on runtime device type detection.
+</p>
+
+<p>
+Because TVs are stationary, indoor devices, they don't have built-in GPS. If your application uses location 
+information, allow users to search for a location or use a "static" location provider to get 
+a location from the zip code configured during the TV setup.
+<pre>
+LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
+Location location = locationManager.getLastKnownLocation("static");
+Geocoder geocoder = new Geocoder(this);
+Address address = null;
+
+try {
+  address = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1).get(0);
+  Log.d("Zip code", address.getPostalCode());
+
+} catch (IOException e) {
+  Log.e(TAG, "Geocoder error", e);
+}
+</pre>
+</p>
+
+<p>
+TVs usually don't support microphones, but if you have an application that uses voice control, 
+you can create a mobile device app that takes voice input and then acts as a remote control for a TV.
+</p>
+
+<h2 id="CheckAvailableFeatures">Check for Available Features at Runtime</h2>
+
+<p>
+To check if a feature is available at runtime, call 
+{@link android.content.pm.PackageManager#hasSystemFeature(String)}.
+ This method takes a single argument : a string corresponding to the 
+feature you want to check. For example, to check for touchscreen, use 
+{@link android.content.pm.PackageManager#hasSystemFeature(String)} with the argument 
+{@link android.content.pm.PackageManager#FEATURE_TOUCHSCREEN}.
+</p>
+
+<p>
+The following code snippet demonstrates how to detect device type at runtime based on supported features:
+
+<pre>
+// Check if android.hardware.telephony feature is available.
+if (getPackageManager().hasSystemFeature("android.hardware.telephony")) {
+   Log.d("Mobile Test", "Running on phone");
+// Check if android.hardware.touchscreen feature is available.
+} else if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) {
+   Log.d("Tablet Test", "Running on devices that don't support telphony but have a touchscreen.");
+} else {
+    Log.d("TV Test", "Running on a TV!");
+}
+</pre>
+</p>
+
+<p>
+This is just one example of using runtime checks to deactivate app functionality that depends on features 
+that aren't available on TVs.
+</p>
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index dcda67d..7e92973 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -40,14 +40,8 @@
     // assigned in constructors, freed in finalizer
     final int mNativeCanvas;
     
-    /*  Our native canvas can be either a raster, gl, or picture canvas.
-        If we are raster, then mGL will be null, and mBitmap may or may not be
-        present (our default constructor creates a raster canvas but no
-        java-bitmap is). If we are a gl-based, then mBitmap will be null, and
-        mGL will not be null. Thus both cannot be non-null, but its possible
-        for both to be null.
-    */
-    private Bitmap  mBitmap;    // if not null, mGL must be null
+    // may be null
+    private Bitmap mBitmap;
     
     // optional field set by the caller
     private DrawFilter mDrawFilter;
@@ -66,7 +60,7 @@
     
     // Used by native code
     @SuppressWarnings({"UnusedDeclaration"})
-    private int         mSurfaceFormat;
+    private int mSurfaceFormat;
 
     /**
      * Flag for drawTextRun indicating left-to-right run direction.
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 18a0a0c..cd5300d 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -184,9 +184,9 @@
 
     private int getIDSafe() {
         if (mAdaptedAllocation != null) {
-            return mAdaptedAllocation.getID();
+            return mAdaptedAllocation.getID(mRS);
         }
-        return getID();
+        return getID(mRS);
     }
 
 
@@ -321,7 +321,7 @@
     @Override
     void updateFromNative() {
         super.updateFromNative();
-        int typeID = mRS.nAllocationGetType(getID());
+        int typeID = mRS.nAllocationGetType(getID(mRS));
         if(typeID != 0) {
             mType = new Type(typeID, mRS);
             mType.updateFromNative();
@@ -371,7 +371,7 @@
                 "Can only send buffer if IO_OUTPUT usage specified.");
         }
         mRS.validate();
-        mRS.nAllocationIoSend(getID());
+        mRS.nAllocationIoSend(getID(mRS));
     }
 
     /**
@@ -394,7 +394,7 @@
                 "Can only receive if IO_INPUT usage specified.");
         }
         mRS.validate();
-        mRS.nAllocationIoReceive(getID());
+        mRS.nAllocationIoReceive(getID(mRS));
     }
 
     /**
@@ -411,7 +411,7 @@
         }
         int i[] = new int[d.length];
         for (int ct=0; ct < d.length; ct++) {
-            i[ct] = d[ct].getID();
+            i[ct] = d[ct].getID(mRS);
         }
         copy1DRangeFromUnchecked(0, mCurrentCount, i);
     }
@@ -571,7 +571,7 @@
         mRS.validate();
         validateBitmapSize(b);
         validateBitmapFormat(b);
-        mRS.nAllocationCopyFromBitmap(getID(), b);
+        mRS.nAllocationCopyFromBitmap(getID(mRS), b);
     }
 
     /**
@@ -652,7 +652,7 @@
      * followup sync will be required.
      */
     public void generateMipmaps() {
-        mRS.nAllocationGenerateMipmaps(getID());
+        mRS.nAllocationGenerateMipmaps(getID(mRS));
     }
 
     /**
@@ -780,7 +780,7 @@
     public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
         mRS.nAllocationData2D(getIDSafe(), off, 0,
                               mSelectedLOD, mSelectedFace.mID,
-                              count, 1, data.getID(), dataOff, 0,
+                              count, 1, data.getID(mRS), dataOff, 0,
                               data.mSelectedLOD, data.mSelectedFace.mID);
     }
 
@@ -857,7 +857,7 @@
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
                               mSelectedLOD, mSelectedFace.mID,
-                              w, h, data.getID(), dataXoff, dataYoff,
+                              w, h, data.getID(mRS), dataXoff, dataYoff,
                               data.mSelectedLOD, data.mSelectedFace.mID);
     }
 
@@ -888,7 +888,7 @@
         mRS.validate();
         validateBitmapFormat(b);
         validateBitmapSize(b);
-        mRS.nAllocationCopyToBitmap(getID(), b);
+        mRS.nAllocationCopyToBitmap(getID(mRS), b);
     }
 
     /**
@@ -901,7 +901,7 @@
     public void copyTo(byte[] d) {
         validateIsInt8();
         mRS.validate();
-        mRS.nAllocationRead(getID(), d);
+        mRS.nAllocationRead(getID(mRS), d);
     }
 
     /**
@@ -914,7 +914,7 @@
     public void copyTo(short[] d) {
         validateIsInt16();
         mRS.validate();
-        mRS.nAllocationRead(getID(), d);
+        mRS.nAllocationRead(getID(mRS), d);
     }
 
     /**
@@ -927,7 +927,7 @@
     public void copyTo(int[] d) {
         validateIsInt32();
         mRS.validate();
-        mRS.nAllocationRead(getID(), d);
+        mRS.nAllocationRead(getID(mRS), d);
     }
 
     /**
@@ -940,7 +940,7 @@
     public void copyTo(float[] d) {
         validateIsFloat32();
         mRS.validate();
-        mRS.nAllocationRead(getID(), d);
+        mRS.nAllocationRead(getID(mRS), d);
     }
 
     /**
@@ -959,10 +959,10 @@
         if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
             throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
         }
-        mRS.nAllocationResize1D(getID(), dimX);
+        mRS.nAllocationResize1D(getID(mRS), dimX);
         mRS.finish();  // Necessary because resize is fifoed and update is async.
 
-        int typeID = mRS.nAllocationGetType(getID());
+        int typeID = mRS.nAllocationGetType(getID(mRS));
         mType = new Type(typeID, mRS);
         mType.updateFromNative();
         updateCacheInfo(mType);
@@ -991,10 +991,10 @@
             throw new RSInvalidStateException(
                 "Resize only support for 2D allocations at this time.");
         }
-        mRS.nAllocationResize2D(getID(), dimX, dimY);
+        mRS.nAllocationResize2D(getID(mRS), dimX, dimY);
         mRS.finish();  // Necessary because resize is fifoed and update is async.
 
-        int typeID = mRS.nAllocationGetType(getID());
+        int typeID = mRS.nAllocationGetType(getID(mRS));
         mType = new Type(typeID, mRS);
         mType.updateFromNative();
         updateCacheInfo(mType);
@@ -1019,10 +1019,10 @@
      */
     static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
         rs.validate();
-        if (type.getID() == 0) {
+        if (type.getID(rs) == 0) {
             throw new RSInvalidStateException("Bad Type");
         }
-        int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, 0);
+        int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -1043,10 +1043,10 @@
     static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips,
                                          int usage, int pointer) {
         rs.validate();
-        if (type.getID() == 0) {
+        if (type.getID(rs) == 0) {
             throw new RSInvalidStateException("Bad Type");
         }
-        int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, pointer);
+        int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, pointer);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -1101,7 +1101,7 @@
         b.setX(count);
         Type t = b.create();
 
-        int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage, 0);
+        int id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -1168,7 +1168,7 @@
         rs.validate();
         Type t = typeFromBitmap(rs, b, mips);
 
-        int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
+        int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
         if (id == 0) {
             throw new RSRuntimeException("Load failed.");
         }
@@ -1186,9 +1186,9 @@
             throw new RSInvalidStateException("Allocation is not a surface texture.");
         }
 
-        int id = mRS.nAllocationGetSurfaceTextureID(getID());
+        int id = mRS.nAllocationGetSurfaceTextureID(getID(mRS));
         SurfaceTexture st = new SurfaceTexture(id);
-        mRS.nAllocationGetSurfaceTextureID2(getID(), st);
+        mRS.nAllocationGetSurfaceTextureID2(getID(mRS), st);
 
         return st;
     }
@@ -1211,7 +1211,7 @@
             throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
         }
 
-        mRS.nAllocationSetSurface(getID(), sur);
+        mRS.nAllocationSetSurface(getID(mRS), sur);
     }
 
     /**
@@ -1224,7 +1224,7 @@
         }
 
         Surface s = new Surface(st);
-        mRS.nAllocationSetSurface(getID(), s);
+        mRS.nAllocationSetSurface(getID(mRS), s);
     }
 
     /**
@@ -1283,7 +1283,7 @@
         tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
         Type t = tb.create();
 
-        int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
+        int id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
         if(id == 0) {
             throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
         }
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index d38f2df..85d86e5 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -30,7 +30,7 @@
         mAdaptedAllocation = alloc;
     }
 
-    int getID() {
+    int getID(RenderScript rs) {
         throw new RSInvalidStateException(
             "This operation is not supported with adapters at this time.");
     }
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index 2e55c48..f464f9b 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -43,16 +43,22 @@
      * Lookup the native object ID for this object.  Primarily used by the
      * generated reflected code.
      *
+     * @param rs Context to verify against internal context for
+     *           match.
      *
      * @return int
      */
-    int getID() {
+    int getID(RenderScript rs) {
+        mRS.validate();
         if (mDestroyed) {
             throw new RSInvalidStateException("using a destroyed object.");
         }
         if (mID == 0) {
             throw new RSRuntimeException("Internal error: Object id 0.");
         }
+        if ((rs != null) && (rs != mRS)) {
+            throw new RSInvalidStateException("using object with mismatched context.");
+        }
         return mID;
     }
 
@@ -138,7 +144,7 @@
      */
     void updateFromNative() {
         mRS.validate();
-        mName = mRS.nGetName(getID());
+        mName = mRS.nGetName(getID(mRS));
     }
 
     /**
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 3d4951f..d75c951 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -778,7 +778,7 @@
 
         // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
         int[] dataBuffer = new int[5];
-        mRS.nElementGetNativeData(getID(), dataBuffer);
+        mRS.nElementGetNativeData(getID(mRS), dataBuffer);
 
         mNormalized = dataBuffer[2] == 1 ? true : false;
         mVectorSize = dataBuffer[3];
@@ -803,7 +803,7 @@
             mOffsetInBytes = new int[numSubElements];
 
             int[] subElementIds = new int[numSubElements];
-            mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes);
+            mRS.nElementGetSubElements(getID(mRS), subElementIds, mElementNames, mArraySizes);
             for(int i = 0; i < numSubElements; i ++) {
                 mElements[i] = new Element(subElementIds[i], mRS);
                 mElements[i].updateFromNative();
@@ -1062,7 +1062,7 @@
 
             int[] ids = new int[ein.length];
             for (int ct = 0; ct < ein.length; ct++ ) {
-                ids[ct] = ein[ct].getID();
+                ids[ct] = ein[ct].getID(mRS);
             }
             int id = mRS.nElementCreate2(ids, sin, asin);
             return new Element(id, mRS, ein, sin, asin);
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index 2739a4b8..a215a57 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -143,7 +143,7 @@
 
     public void addObj(BaseObj obj) {
         if (obj != null) {
-            addI32(obj.getID());
+            addI32(obj.getID(null));
         } else {
             addI32(0);
         }
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index b5419a7..61793171 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -165,7 +165,7 @@
     }
 
     private void initEntries() {
-        int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID());
+        int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID(mRS));
         if(numFileEntries <= 0) {
             return;
         }
@@ -174,10 +174,10 @@
         int[] ids = new int[numFileEntries];
         String[] names = new String[numFileEntries];
 
-        mRS.nFileA3DGetIndexEntries(getID(), numFileEntries, ids, names);
+        mRS.nFileA3DGetIndexEntries(getID(mRS), numFileEntries, ids, names);
 
         for(int i = 0; i < numFileEntries; i ++) {
-            mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], EntryType.toEntryType(ids[i]));
+            mFileEntries[i] = new IndexEntry(mRS, i, getID(mRS), names[i], EntryType.toEntryType(ids[i]));
         }
     }
 
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index f641117..ffbb41d 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -137,15 +137,15 @@
     @Override
     void updateFromNative() {
         super.updateFromNative();
-        int vtxCount = mRS.nMeshGetVertexBufferCount(getID());
-        int idxCount = mRS.nMeshGetIndexCount(getID());
+        int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS));
+        int idxCount = mRS.nMeshGetIndexCount(getID(mRS));
 
         int[] vtxIDs = new int[vtxCount];
         int[] idxIDs = new int[idxCount];
         int[] primitives = new int[idxCount];
 
-        mRS.nMeshGetVertices(getID(), vtxIDs, vtxCount);
-        mRS.nMeshGetIndices(getID(), idxIDs, primitives, idxCount);
+        mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount);
+        mRS.nMeshGetIndices(getID(mRS), idxIDs, primitives, idxCount);
 
         mVertexBuffers = new Allocation[vtxCount];
         mIndexBuffers = new Allocation[idxCount];
@@ -343,7 +343,7 @@
                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                 }
                 vertexBuffers[ct] = alloc;
-                vtx[ct] = alloc.getID();
+                vtx[ct] = alloc.getID(mRS);
             }
 
             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
@@ -354,7 +354,7 @@
                 } else if(entry.e != null) {
                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                 }
-                int allocID = (alloc == null) ? 0 : alloc.getID();
+                int allocID = (alloc == null) ? 0 : alloc.getID(mRS);
                 indexBuffers[ct] = alloc;
                 primitives[ct] = entry.prim;
 
@@ -483,12 +483,12 @@
             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
                 Entry entry = mVertexTypes[ct];
                 vertexBuffers[ct] = entry.a;
-                vtx[ct] = entry.a.getID();
+                vtx[ct] = entry.a.getID(mRS);
             }
 
             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
-                int allocID = (entry.a == null) ? 0 : entry.a.getID();
+                int allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
                 indexBuffers[ct] = entry.a;
                 primitives[ct] = entry.prim;
 
diff --git a/graphics/java/android/renderscript/Path.java b/graphics/java/android/renderscript/Path.java
index 83ae150..9c4d41b 100644
--- a/graphics/java/android/renderscript/Path.java
+++ b/graphics/java/android/renderscript/Path.java
@@ -67,7 +67,7 @@
 
 
     public static Path createStaticPath(RenderScript rs, Primitive p, float quality, Allocation vtx) {
-        int id = rs.nPathCreate(p.mID, false, vtx.getID(), 0, quality);
+        int id = rs.nPathCreate(p.mID, false, vtx.getID(rs), 0, quality);
         Path newPath = new Path(id, rs, p, null, null, quality);
         return newPath;
     }
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index 4d60ac8..104d1cd 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -134,11 +134,11 @@
             throw new IllegalArgumentException("Slot ID out of range.");
         }
         if (a != null &&
-            a.getType().getID() != mConstants[slot].getID()) {
+            a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
             throw new IllegalArgumentException("Allocation type does not match slot type.");
         }
-        int id = a != null ? a.getID() : 0;
-        mRS.nProgramBindConstants(getID(), slot, id);
+        int id = a != null ? a.getID(mRS) : 0;
+        mRS.nProgramBindConstants(getID(mRS), slot, id);
     }
 
     /**
@@ -159,8 +159,8 @@
             throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
         }
 
-        int id = va != null ? va.getID() : 0;
-        mRS.nProgramBindTexture(getID(), slot, id);
+        int id = va != null ? va.getID(mRS) : 0;
+        mRS.nProgramBindTexture(getID(mRS), slot, id);
     }
 
     /**
@@ -179,8 +179,8 @@
             throw new IllegalArgumentException("Slot ID out of range.");
         }
 
-        int id = vs != null ? vs.getID() : 0;
-        mRS.nProgramBindSampler(getID(), slot, id);
+        int id = vs != null ? vs.getID(mRS) : 0;
+        mRS.nProgramBindSampler(getID(mRS), slot, id);
     }
 
 
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index ebc15e5..fa6e2d4 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -64,15 +64,15 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID();
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID();
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID();
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
index cd31db3..14f10f1 100644
--- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -52,15 +52,15 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID();
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID();
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID();
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index a6cd15b..32c908e 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -121,15 +121,15 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID();
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID();
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID();
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
index 9a43943..fac4c3d 100644
--- a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -75,15 +75,15 @@
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = mInputs[i].getID();
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = mOutputs[i].getID();
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = mConstants[i].getID();
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index dffd400..03294b5 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -1000,7 +1000,7 @@
 
     int safeID(BaseObj o) {
         if(o != null) {
-            return o.getID();
+            return o.getID(this);
         }
         return 0;
     }
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index d00c428..4f59ae3 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -26,7 +26,7 @@
      * @param slot
      */
     protected void invoke(int slot) {
-        mRS.nScriptInvoke(getID(), slot);
+        mRS.nScriptInvoke(getID(mRS), slot);
     }
 
     /**
@@ -37,9 +37,9 @@
      */
     protected void invoke(int slot, FieldPacker v) {
         if (v != null) {
-            mRS.nScriptInvokeV(getID(), slot, v.getData());
+            mRS.nScriptInvokeV(getID(mRS), slot, v.getData());
         } else {
-            mRS.nScriptInvoke(getID(), slot);
+            mRS.nScriptInvoke(getID(mRS), slot);
         }
     }
 
@@ -58,17 +58,17 @@
         }
         int in_id = 0;
         if (ain != null) {
-            in_id = ain.getID();
+            in_id = ain.getID(mRS);
         }
         int out_id = 0;
         if (aout != null) {
-            out_id = aout.getID();
+            out_id = aout.getID(mRS);
         }
         byte[] params = null;
         if (v != null) {
             params = v.getData();
         }
-        mRS.nScriptForEach(getID(), slot, in_id, out_id, params);
+        mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params);
     }
 
 
@@ -86,9 +86,9 @@
     public void bindAllocation(Allocation va, int slot) {
         mRS.validate();
         if (va != null) {
-            mRS.nScriptBindAllocation(getID(), va.getID(), slot);
+            mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot);
         } else {
-            mRS.nScriptBindAllocation(getID(), 0, slot);
+            mRS.nScriptBindAllocation(getID(mRS), 0, slot);
         }
     }
 
@@ -99,7 +99,7 @@
      * @param v
      */
     public void setVar(int index, float v) {
-        mRS.nScriptSetVarF(getID(), index, v);
+        mRS.nScriptSetVarF(getID(mRS), index, v);
     }
 
     /**
@@ -109,7 +109,7 @@
      * @param v
      */
     public void setVar(int index, double v) {
-        mRS.nScriptSetVarD(getID(), index, v);
+        mRS.nScriptSetVarD(getID(mRS), index, v);
     }
 
     /**
@@ -119,7 +119,7 @@
      * @param v
      */
     public void setVar(int index, int v) {
-        mRS.nScriptSetVarI(getID(), index, v);
+        mRS.nScriptSetVarI(getID(mRS), index, v);
     }
 
     /**
@@ -129,7 +129,7 @@
      * @param v
      */
     public void setVar(int index, long v) {
-        mRS.nScriptSetVarJ(getID(), index, v);
+        mRS.nScriptSetVarJ(getID(mRS), index, v);
     }
 
     /**
@@ -139,7 +139,7 @@
      * @param v
      */
     public void setVar(int index, boolean v) {
-        mRS.nScriptSetVarI(getID(), index, v ? 1 : 0);
+        mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0);
     }
 
     /**
@@ -149,7 +149,7 @@
      * @param o
      */
     public void setVar(int index, BaseObj o) {
-        mRS.nScriptSetVarObj(getID(), index, (o == null) ? 0 : o.getID());
+        mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS));
     }
 
     /**
@@ -159,13 +159,13 @@
      * @param v
      */
     public void setVar(int index, FieldPacker v) {
-        mRS.nScriptSetVarV(getID(), index, v.getData());
+        mRS.nScriptSetVarV(getID(mRS), index, v.getData());
     }
 
     public void setTimeZone(String timeZone) {
         mRS.validate();
         try {
-            mRS.nScriptSetTimeZone(getID(), timeZone.getBytes("UTF-8"));
+            mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"));
         } catch (java.io.UnsupportedEncodingException e) {
             throw new RuntimeException(e);
         }
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index 70d1de4..a707df2 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -180,7 +180,7 @@
         // We have 6 integer to obtain mDimX; mDimY; mDimZ;
         // mDimLOD; mDimFaces; mElement;
         int[] dataBuffer = new int[6];
-        mRS.nTypeGetNativeData(getID(), dataBuffer);
+        mRS.nTypeGetNativeData(getID(mRS), dataBuffer);
 
         mDimX = dataBuffer[0];
         mDimY = dataBuffer[1];
@@ -280,7 +280,8 @@
                 }
             }
 
-            int id = mRS.nTypeCreate(mElement.getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
+            int id = mRS.nTypeCreate(mElement.getID(mRS),
+                                     mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
             Type t = new Type(id, mRS);
             t.mElement = mElement;
             t.mDimX = mDimX;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f37bfd2..9f2bacd 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -112,6 +112,7 @@
     mClipChildren = true;
     mAlpha = 1;
     mMultipliedAlpha = 255;
+    mHasOverlappingRendering = true;
     mTranslationX = 0;
     mTranslationY = 0;
     mRotation = 0;
@@ -772,18 +773,23 @@
             }
         }
         if (mAlpha < 1 && !mCaching) {
-            // TODO: should be able to store the size of a DL at record time and not
-            // have to pass it into this call. In fact, this information might be in the
-            // location/size info that we store with the new native transform data.
-            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
-            if (mClipChildren) {
-                flags |= SkCanvas::kClipToLayer_SaveFlag;
+            if (!mHasOverlappingRendering) {
+                DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
+                renderer.setAlpha(mAlpha);
+            } else {
+                // TODO: should be able to store the size of a DL at record time and not
+                // have to pass it into this call. In fact, this information might be in the
+                // location/size info that we store with the new native transform data.
+                int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+                if (mClipChildren) {
+                    flags |= SkCanvas::kClipToLayer_SaveFlag;
+                }
+                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+                        (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
+                        mMultipliedAlpha, flags);
+                renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
+                        mMultipliedAlpha, flags);
             }
-            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
-                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
-                    mMultipliedAlpha, flags);
-            renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
-                    mMultipliedAlpha, flags);
         }
         if (mClipChildren) {
             DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 38b0a6d..fe0c94d 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -181,6 +181,10 @@
         }
     }
 
+    void setHasOverlappingRendering(bool hasOverlappingRendering) {
+        mHasOverlappingRendering = hasOverlappingRendering;
+    }
+
     void setTranslationX(float translationX) {
         if (translationX != mTranslationX) {
             mTranslationX = translationX;
@@ -496,6 +500,7 @@
     bool mClipChildren;
     float mAlpha;
     int mMultipliedAlpha;
+    bool mHasOverlappingRendering;
     float mTranslationX, mTranslationY;
     float mRotation, mRotationX, mRotationY;
     float mScaleX, mScaleY;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 115787c..216c451 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -631,6 +631,9 @@
     const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
 
     if (fboLayer) {
+        // Detach the texture from the FBO
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+
         // Unbind current FBO and restore previous one
         glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
     }
@@ -671,11 +674,6 @@
         //       code path
         // See LayerRenderer::destroyLayer(Layer*)
 
-        // Detach the texture from the FBO
-        glBindFramebuffer(GL_FRAMEBUFFER, current->fbo);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-        glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
-
         // Put the FBO name back in the cache, if it doesn't fit, it will be destroyed
         mCaches.fboCache.put(current->fbo);
         layer->setFbo(0);
@@ -1101,6 +1099,7 @@
 
 void OpenGLRenderer::setupDrawColor(int color, int alpha) {
     mColorA = alpha / 255.0f;
+    mColorA *= mSnapshot->alpha;
     // Second divide of a by 255 is an optimization, allowing us to simply multiply
     // the rgb values by a instead of also dividing by 255
     const float a = mColorA / 255.0f;
@@ -2800,6 +2799,7 @@
         *mode = SkXfermode::kSrcOver_Mode;
         *alpha = 255;
     }
+    *alpha *= mSnapshot->alpha;
 }
 
 SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index b651904..ab137cc 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -85,6 +85,10 @@
     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
             int alpha, int flags);
 
+    virtual void setAlpha(float alpha) {
+        mSnapshot->alpha = alpha;
+    }
+
     virtual void translate(float dx, float dy);
     virtual void rotate(float degrees);
     virtual void scale(float sx, float sy);
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index de2c674..5d5961a 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -26,7 +26,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0),
-        invisible(false), empty(false) {
+        invisible(false), empty(false), alpha(1.0f) {
 
     transform = &mTransformRoot;
     clipRect = &mClipRectRoot;
@@ -41,7 +41,7 @@
 Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
         flags(0), previous(s), layer(NULL), fbo(s->fbo),
         invisible(s->invisible), empty(false),
-        viewport(s->viewport), height(s->height) {
+        viewport(s->viewport), height(s->height), alpha(s->alpha) {
 
     clipRegion = NULL;
 
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index b2bc879..30b03fc 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -208,6 +208,17 @@
      */
     Region* region;
 
+    /**
+     * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
+     * has translucent rendering in a non-overlapping View. This value will be used by
+     * the renderer to set the alpha in the current color being used for ensuing drawing
+     * operations. The value is inherited by child snapshots because the same value should
+     * be applied to descendents of the current DisplayList (for example, a TextView contains
+     * the base alpha value which should be applied to the child DisplayLists used for drawing
+     * the actual text).
+     */
+    float alpha;
+
 private:
     void ensureClipRegion();
     void copyClipRectFromRegion();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 5f6a61d..c66a03f 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -92,7 +92,7 @@
     protected static final boolean DEBUG_RC = false;
 
     /** How long to delay before persisting a change in volume/ringer mode. */
-    private static final int PERSIST_DELAY = 3000;
+    private static final int PERSIST_DELAY = 500;
 
     private Context mContext;
     private ContentResolver mContentResolver;
@@ -861,8 +861,9 @@
                 // Post a persist master volume msg
                 sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME, SENDMSG_REPLACE,
                         Math.round(volume * (float)1000.0), 0, null, PERSIST_DELAY);
-                sendMasterVolumeUpdate(flags, oldVolume, newVolume);
             }
+            // Send the volume update regardless whether there was a change.
+            sendMasterVolumeUpdate(flags, oldVolume, newVolume);
         }
     }
 
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index d06e302..7629d60 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -83,7 +83,6 @@
     public native final void release();
 
     public static int CONFIGURE_FLAG_ENCODE = 1;
-    public static int CONFIGURE_FLAG_SECURE = 2;
 
     /** Configures a component.
      *  @param format A map of string/value pairs describing the input format
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
new file mode 100644
index 0000000..b46ce96
--- /dev/null
+++ b/media/java/android/media/MediaCodecList.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * MediaCodecList class can be used to enumerate available codecs,
+ * find a codec supporting a given format and query the capabilities
+ * of a given codec.
+ * @hide
+*/
+final public class MediaCodecList {
+    public static native final int countCodecs();
+    public static native final String getCodecName(int index);
+    public static native final boolean isEncoder(int index);
+    public static native final String[] getSupportedTypes(int index);
+
+    public static final class CodecProfileLevel {
+        public int mProfile;
+        public int mLevel;
+    };
+
+    public static final class CodecCapabilities {
+        public CodecProfileLevel[] mProfileLevels;
+        public int[] mColorFormats;
+    };
+    public static native final CodecCapabilities getCodecCapabilities(
+            int index, String type);
+
+    private static native final void native_init();
+
+    private MediaCodecList() {}
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+}
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 7f7e284..c9bec18 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -179,6 +179,7 @@
         if (isWMAEnabled()) {
             addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma", MtpConstants.FORMAT_WMA);
         }
+        addFileType("OGG", FILE_TYPE_OGG, "audio/ogg", MtpConstants.FORMAT_OGG);
         addFileType("OGG", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG);
         addFileType("OGA", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG);
         addFileType("AAC", FILE_TYPE_AAC, "audio/aac", MtpConstants.FORMAT_AAC);
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index fcc3b13..dd1e505 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -3,6 +3,7 @@
 
 LOCAL_SRC_FILES:= \
     android_media_MediaCodec.cpp \
+    android_media_MediaCodecList.cpp \
     android_media_MediaExtractor.cpp \
     android_media_MediaPlayer.cpp \
     android_media_MediaRecorder.cpp \
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 04d7c22..4b7a811 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -29,6 +29,7 @@
 #include <gui/Surface.h>
 #include <gui/SurfaceTextureClient.h>
 
+#include <media/ICrypto.h>
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -102,7 +103,7 @@
     if (surfaceTexture != NULL) {
         client = new SurfaceTextureClient(surfaceTexture);
     }
-    return mCodec->configure(format, client, flags);
+    return mCodec->configure(format, client, NULL /* crypto */, flags);
 }
 
 status_t JMediaCodec::start() {
@@ -387,7 +388,7 @@
 
     if (codec == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
+        return 0;
     }
 
     size_t index;
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
new file mode 100644
index 0000000..2b8f91e
--- /dev/null
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_NDEBUG 0
+#define LOG_TAG "MediaCodec-JNI"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaCodecList.h>
+
+#include "android_runtime/AndroidRuntime.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+using namespace android;
+
+static jint android_media_MediaCodecList_countCodecs(
+        JNIEnv *env, jobject thiz) {
+    return MediaCodecList::getInstance()->countCodecs();
+}
+
+static jstring android_media_MediaCodecList_getCodecName(
+        JNIEnv *env, jobject thiz, jint index) {
+    const char *name = MediaCodecList::getInstance()->getCodecName(index);
+
+    if (name == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return NULL;
+    }
+
+    return env->NewStringUTF(name);
+}
+
+static jboolean android_media_MediaCodecList_isEncoder(
+        JNIEnv *env, jobject thiz, jint index) {
+    return MediaCodecList::getInstance()->isEncoder(index);
+}
+
+static jarray android_media_MediaCodecList_getSupportedTypes(
+        JNIEnv *env, jobject thiz, jint index) {
+    Vector<AString> types;
+    status_t err =
+        MediaCodecList::getInstance()->getSupportedTypes(index, &types);
+
+    if (err != OK) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return NULL;
+    }
+
+    jclass clazz = env->FindClass("java/lang/String");
+    CHECK(clazz != NULL);
+
+    jobjectArray array = env->NewObjectArray(types.size(), clazz, NULL);
+
+    for (size_t i = 0; i < types.size(); ++i) {
+        jstring obj = env->NewStringUTF(types.itemAt(i).c_str());
+        env->SetObjectArrayElement(array, i, obj);
+        env->DeleteLocalRef(obj);
+        obj = NULL;
+    }
+
+    return array;
+}
+
+static jobject android_media_MediaCodecList_getCodecCapabilities(
+        JNIEnv *env, jobject thiz, jint index, jstring type) {
+    if (type == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return NULL;
+    }
+
+    const char *typeStr = env->GetStringUTFChars(type, NULL);
+
+    if (typeStr == NULL) {
+        // Out of memory exception already pending.
+        return NULL;
+    }
+
+    Vector<MediaCodecList::ProfileLevel> profileLevels;
+    Vector<uint32_t> colorFormats;
+
+    status_t err =
+        MediaCodecList::getInstance()->getCodecCapabilities(
+                index, typeStr, &profileLevels, &colorFormats);
+
+    env->ReleaseStringUTFChars(type, typeStr);
+    typeStr = NULL;
+
+    if (err != OK) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return NULL;
+    }
+
+    jclass capsClazz =
+        env->FindClass("android/media/MediaCodecList$CodecCapabilities");
+    CHECK(capsClazz != NULL);
+
+    jobject caps = env->AllocObject(capsClazz);
+
+    jclass profileLevelClazz =
+        env->FindClass("android/media/MediaCodecList$CodecProfileLevel");
+    CHECK(profileLevelClazz != NULL);
+
+    jobjectArray profileLevelArray =
+        env->NewObjectArray(profileLevels.size(), profileLevelClazz, NULL);
+
+    jfieldID profileField =
+        env->GetFieldID(profileLevelClazz, "mProfile", "I");
+
+    jfieldID levelField =
+        env->GetFieldID(profileLevelClazz, "mLevel", "I");
+
+    for (size_t i = 0; i < profileLevels.size(); ++i) {
+        const MediaCodecList::ProfileLevel &src = profileLevels.itemAt(i);
+
+        jobject profileLevelObj = env->AllocObject(profileLevelClazz);
+
+        env->SetIntField(profileLevelObj, profileField, src.mProfile);
+        env->SetIntField(profileLevelObj, levelField, src.mLevel);
+
+        env->SetObjectArrayElement(profileLevelArray, i, profileLevelObj);
+
+        env->DeleteLocalRef(profileLevelObj);
+        profileLevelObj = NULL;
+    }
+
+    jfieldID profileLevelsField = env->GetFieldID(
+            capsClazz,
+            "mProfileLevels",
+            "[Landroid/media/MediaCodecList$CodecProfileLevel;");
+
+    env->SetObjectField(caps, profileLevelsField, profileLevelArray);
+
+    env->DeleteLocalRef(profileLevelArray);
+    profileLevelArray = NULL;
+
+    jintArray colorFormatsArray = env->NewIntArray(colorFormats.size());
+
+    for (size_t i = 0; i < colorFormats.size(); ++i) {
+        jint val = colorFormats.itemAt(i);
+        env->SetIntArrayRegion(colorFormatsArray, i, 1, &val);
+    }
+
+    jfieldID colorFormatsField = env->GetFieldID(
+            capsClazz, "mColorFormats", "[I");
+
+    env->SetObjectField(caps, colorFormatsField, colorFormatsArray);
+
+    env->DeleteLocalRef(colorFormatsArray);
+    colorFormatsArray = NULL;
+
+    return caps;
+}
+
+static void android_media_MediaCodecList_native_init(JNIEnv *env) {
+}
+
+static JNINativeMethod gMethods[] = {
+    { "countCodecs", "()I", (void *)android_media_MediaCodecList_countCodecs },
+    { "getCodecName", "(I)Ljava/lang/String;",
+      (void *)android_media_MediaCodecList_getCodecName },
+    { "isEncoder", "(I)Z", (void *)android_media_MediaCodecList_isEncoder },
+    { "getSupportedTypes", "(I)[Ljava/lang/String;",
+      (void *)android_media_MediaCodecList_getSupportedTypes },
+
+    { "getCodecCapabilities",
+      "(ILjava/lang/String;)Landroid/media/MediaCodecList$CodecCapabilities;",
+      (void *)android_media_MediaCodecList_getCodecCapabilities },
+
+    { "native_init", "()V", (void *)android_media_MediaCodecList_native_init },
+};
+
+int register_android_media_MediaCodecList(JNIEnv *env) {
+    return AndroidRuntime::registerNativeMethods(env,
+                "android/media/MediaCodecList", gMethods, NELEM(gMethods));
+}
+
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 745e253..3074bb1 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -881,6 +881,7 @@
 
 extern int register_android_media_MediaCodec(JNIEnv *env);
 extern int register_android_media_MediaExtractor(JNIEnv *env);
+extern int register_android_media_MediaCodecList(JNIEnv *env);
 extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
 extern int register_android_media_MediaRecorder(JNIEnv *env);
 extern int register_android_media_MediaScanner(JNIEnv *env);
@@ -962,6 +963,11 @@
         goto bail;
     }
 
+    if (register_android_media_MediaCodecList(env) < 0) {
+        ALOGE("ERROR: MediaCodec native registration failed");
+        goto bail;
+    }
+
     /* success -- return valid version number */
     result = JNI_VERSION_1_4;
 
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index dd5e026..b698705 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,7 +16,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.mediaframeworktest">
-    
+
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.INTERNET" />
@@ -24,7 +24,7 @@
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
 
-    <application>    
+    <application>
         <uses-library android:name="android.test.runner" />
         <activity android:label="@string/app_name"
                 android:name="MediaFrameworkTest"
@@ -34,12 +34,18 @@
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
-    </application>   
+    </application>
+
+    <instrumentation android:name=".CameraStressTestRunner"
+        android:targetPackage="com.android.mediaframeworktest"
+        android:label="Camera stress tests InstrumentationRunner">
+    </instrumentation>
+
     <instrumentation android:name=".MediaFrameworkTestRunner"
          android:targetPackage="com.android.mediaframeworktest"
          android:label="MediaFramework tests InstrumentationRunner">
      </instrumentation>
-     
+
       <instrumentation android:name=".MediaFrameworkPerfTestRunner"
          android:targetPackage="com.android.mediaframeworktest"
          android:label="MediaFramework Performance tests InstrumentationRunner">
@@ -49,7 +55,7 @@
          android:targetPackage="com.android.mediaframeworktest"
          android:label="MediaFramework unit tests InstrumentationRunner">
      </instrumentation>
-     
+
      <instrumentation android:name=".MediaRecorderStressTestRunner"
          android:targetPackage="com.android.mediaframeworktest"
          android:label="MediaRecorder stress tests InstrumentationRunner">
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java
new file mode 100644
index 0000000..fa59fa4
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mediaframeworktest;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import com.android.mediaframeworktest.stress.CameraStressTest;
+
+import junit.framework.TestSuite;
+
+public class CameraStressTestRunner extends InstrumentationTestRunner {
+
+    @Override
+    public TestSuite getAllTests() {
+        TestSuite suite = new InstrumentationTestSuite(this);
+        suite.addTestSuite(CameraStressTest.class);
+        return suite;
+    }
+
+    @Override
+    public ClassLoader getLoader() {
+        return CameraStressTestRunner.class.getClassLoader();
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
new file mode 100644
index 0000000..a9c6119
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mediaframeworktest.stress;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.FileWriter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import android.hardware.Camera;
+import android.hardware.Camera.PictureCallback;
+import android.hardware.Camera.ShutterCallback;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import com.android.mediaframeworktest.CameraStressTestRunner;
+
+import junit.framework.Assert;
+
+/**
+ * Junit / Instrumentation test case for the camera zoom api
+ *
+ * adb shell am instrument
+ *  -e class com.android.mediaframeworktest.stress.CameraStressTest
+ *  -w com.android.mediaframeworktest/.CameraStressTestRunner
+ */
+public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+    private String TAG = "CameraStressTest";
+    private Camera mCamera;
+
+    private static final int NUMBER_OF_ZOOM_LOOPS = 100;
+    private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds
+    private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
+    private static final long WAIT_ZOOM_ANIMATION = 5 * 1000; // 5 seconds
+    private static final String CAMERA_STRESS_OUTPUT =
+            "/sdcard/cameraStressOutput.txt";
+    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
+
+    private Thread mLooperThread;
+    private Handler mHandler;
+
+    public CameraStressTest() {
+        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+    }
+
+    protected void setUp() throws Exception {
+        final Semaphore sem = new Semaphore(0);
+        mLooperThread = new Thread() {
+            @Override
+            public void run() {
+                Log.v(TAG, "starting looper");
+                Looper.prepare();
+                mHandler = new Handler();
+                sem.release();
+                Looper.loop();
+                Log.v(TAG, "quit looper");
+            }
+        };
+        mLooperThread.start();
+        if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+            fail("Failed to start the looper.");
+        }
+        getActivity();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHandler != null) {
+            mHandler.getLooper().quit();
+            mHandler = null;
+        }
+        if (mLooperThread != null) {
+            mLooperThread.join(WAIT_TIMEOUT);
+            if (mLooperThread.isAlive()) {
+                fail("Failed to stop the looper.");
+            }
+            mLooperThread = null;
+        }
+
+        super.tearDown();
+    }
+
+    private void runOnLooper(final Runnable command) throws InterruptedException {
+        final Semaphore sem = new Semaphore(0);
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    command.run();
+                } finally {
+                    sem.release();
+                }
+            }
+        });
+        if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+            fail("Failed to run the command on the looper.");
+        }
+    }
+
+    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
+        public void onError(int error, android.hardware.Camera camera) {
+            if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
+                assertTrue("Camera test mediaserver died", false);
+            }
+        }
+    }
+
+    private ShutterCallback shutterCallback = new ShutterCallback() {
+        @Override
+        public void onShutter() {
+            Log.v(TAG, "Shutter");
+        }
+    };
+
+    private PictureCallback rawCallback = new PictureCallback() {
+        @Override
+        public void onPictureTaken(byte[] data, Camera camera) {
+            Log.v(TAG, "Raw picture taken");
+        }
+    };
+
+    private PictureCallback jpegCallback = new PictureCallback() {
+        @Override
+        public void onPictureTaken(byte[] data, Camera camera) {
+            FileOutputStream fos = null;
+
+            try {
+                Log.v(TAG, "JPEG picture taken");
+                fos = new FileOutputStream(String.format("%s/zoom-test-%d.jpg",
+                        Environment.getExternalStorageDirectory(), System.currentTimeMillis()));
+                fos.write(data);
+            }
+            catch (FileNotFoundException e) {
+                Log.v(TAG, "File not found: " + e.toString());
+            }
+            catch (IOException e) {
+                Log.v(TAG, "Error accessing file: " + e.toString());
+            }
+            finally {
+                try {
+                    if (fos != null) {
+                        fos.close();
+                    }
+                }
+                catch (IOException e) {
+                    Log.v(TAG, "Error closing file: " + e.toString());
+                }
+            }
+        }
+    };
+
+    // Helper method for cleaning up pics taken during testStressCameraZoom
+    private void cleanupZoomImages() {
+        try {
+            File sdcard = Environment.getExternalStorageDirectory();
+            File[] zoomImages = null;
+
+            FilenameFilter filter = new FilenameFilter() {
+                public boolean accept(File dir, String name) {
+                    return name.startsWith("zoom-test-");
+                }
+            };
+
+            zoomImages = sdcard.listFiles(filter);
+
+            for (File f : zoomImages) {
+                f.delete();
+            }
+        }
+        catch (SecurityException e) {
+            Log.v(TAG, "Security manager access violation: " + e.toString());
+        }
+    }
+
+    // Test case for stressing the camera zoom in/out feature
+    @LargeTest
+    public void testStressCameraZoom() throws Exception {
+        SurfaceHolder mSurfaceHolder;
+        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+        File stressOutFile = new File(CAMERA_STRESS_OUTPUT);
+        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
+        output.write("Camera zoom stress:\n");
+        output.write("Total number of loops: " +  NUMBER_OF_ZOOM_LOOPS + "\n");
+
+        try {
+            Log.v(TAG, "Start preview");
+            output.write("No of loop: ");
+
+            mCamera = Camera.open();
+            Camera.Parameters params = mCamera.getParameters();
+            mCamera.release();
+
+            if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) {
+                Log.v(TAG, "Device camera does not support zoom");
+                assertTrue("Camera zoom stress test", false);
+            }
+            else {
+                Log.v(TAG, "Device camera does support zoom");
+
+                int nextZoomLevel = 0;
+
+                for (int i = 0; i < NUMBER_OF_ZOOM_LOOPS; i++) {
+                    runOnLooper(new Runnable() {
+                        @Override
+                        public void run() {
+                            mCamera = Camera.open();
+                        }
+                    });
+
+                    mCamera.setErrorCallback(mCameraErrorCallback);
+                    mCamera.setPreviewDisplay(mSurfaceHolder);
+                    mCamera.startPreview();
+                    Thread.sleep(WAIT_GENERIC);
+
+                    params = mCamera.getParameters();
+                    int currentZoomLevel = params.getZoom();
+
+                    if (nextZoomLevel >= params.getMaxZoom()) {
+                        nextZoomLevel = 0;
+                    }
+                    ++nextZoomLevel;
+
+                    if (params.isSmoothZoomSupported()) {
+                        mCamera.startSmoothZoom(nextZoomLevel);
+                    }
+                    else {
+                        params.setZoom(nextZoomLevel);
+                        mCamera.setParameters(params);
+                    }
+                    Log.v(TAG, "Zooming from " + currentZoomLevel + " to " + nextZoomLevel);
+
+                    // sleep allows for zoom animation to finish
+                    Thread.sleep(WAIT_ZOOM_ANIMATION);
+
+                    // take picture
+                    mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
+                    Thread.sleep(WAIT_GENERIC);
+                    mCamera.stopPreview();
+                    mCamera.release();
+                    output.write(" ," + i);
+                }
+            }
+
+            cleanupZoomImages();
+        }
+        catch (Exception e) {
+            assertTrue("Camera zoom stress test Exception", false);
+            Log.v(TAG, e.toString());
+        }
+        output.write("\n\n");
+        output.close();
+    }
+}
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index aa27861..715ccba 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -66,7 +66,7 @@
             android:layout_height="wrap_content"
             android:textSize="@dimen/status_bar_recents_app_label_text_size"
             android:fadingEdge="horizontal"
-            android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+            android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
             android:scrollHorizontally="true"
             android:layout_alignLeft="@id/app_thumbnail"
             android:layout_below="@id/app_thumbnail"
@@ -82,7 +82,7 @@
             android:layout_height="wrap_content"
             android:textSize="@dimen/status_bar_recents_app_description_text_size"
             android:fadingEdge="horizontal"
-            android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+            android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
             android:scrollHorizontally="true"
             android:layout_alignLeft="@id/app_thumbnail"
             android:layout_below="@id/app_label"
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index 180f022..dba1dd9 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -41,7 +41,7 @@
             android:stackFromBottom="true"
             android:fadingEdge="horizontal"
             android:scrollbars="none"
-            android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+            android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
             android:layout_gravity="bottom|left"
             android:orientation="horizontal"
             android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index bc389f9..ca72530 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -35,7 +35,7 @@
             android:layout_height="wrap_content"
             android:textSize="@dimen/status_bar_recents_app_label_text_size"
             android:fadingEdge="horizontal"
-            android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+            android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
             android:scrollHorizontally="true"
             android:layout_alignParentLeft="true"
             android:layout_alignTop="@id/app_icon"
@@ -89,7 +89,7 @@
             android:layout_height="wrap_content"
             android:textSize="@dimen/status_bar_recents_app_description_text_size"
             android:fadingEdge="horizontal"
-            android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+            android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
             android:scrollHorizontally="true"
             android:layout_alignParentLeft="true"
             android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index e6a077a..73c3da5 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -40,7 +40,7 @@
             android:stackFromBottom="true"
             android:fadingEdge="vertical"
             android:scrollbars="none"
-            android:fadingEdgeLength="@*android:dimen/status_bar_height"
+            android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
             android:layout_gravity="bottom|left"
             android:clipToPadding="false"
             android:clipChildren="false">
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index 333fcda..7d639ec 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -28,7 +28,7 @@
         android:layout_height="wrap_content"
         android:textSize="@dimen/status_bar_recents_app_label_text_size"
         android:fadingEdge="horizontal"
-        android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+        android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
         android:scrollHorizontally="true"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
@@ -86,7 +86,7 @@
         android:layout_height="wrap_content"
         android:textSize="@dimen/status_bar_recents_app_description_text_size"
         android:fadingEdge="horizontal"
-        android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+        android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
         android:scrollHorizontally="true"
         android:layout_alignParentLeft="true"
         android:layout_below="@id/recents_callout_line"
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index ba1cdfa..8c1ac55 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -53,8 +53,10 @@
     <dimen name="status_bar_recents_app_label_width">97dip</dimen>
     <!-- Left margin for application label -->
     <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
-    <!-- Size of fading edge for scroll effect -->
-    <dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
+    <!-- Size of fading edge for text -->
+    <dimen name="status_bar_recents_text_fading_edge_length">20dip</dimen>
+    <!-- Size of fading edge for scrolling -->
+    <dimen name="status_bar_recents_scroll_fading_edge_length">10dip</dimen>
     <!-- Margin between recents container and glow on the right -->
     <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 2c22e3c..4441ca6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -33,8 +33,10 @@
     <dimen name="status_bar_recents_app_label_text_size">14dip</dimen>
     <!-- Size of application description text -->
     <dimen name="status_bar_recents_app_description_text_size">14dip</dimen>
-    <!-- Size of fading edge for scroll effect -->
-    <dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
+    <!-- Size of fading edge for text -->
+    <dimen name="status_bar_recents_text_fading_edge_length">20dip</dimen>
+    <!-- Size of fading edge for scrolling -->
+    <dimen name="status_bar_recents_scroll_fading_edge_length">10dip</dimen>
     <!-- Margin between recents container and glow on the right -->
     <dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
     <!-- Amount to offset bottom of notification peek window from top of status bar. -->
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index ebed522..5d6e315 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -68,6 +68,7 @@
     static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
     private Context mContext;
     private BaseStatusBar mBar;
+    private PopupMenu mPopup;
     private View mRecentsScrim;
     private View mRecentsNoApps;
     private ViewGroup mRecentsContainer;
@@ -313,6 +314,10 @@
             setFocusable(true);
             setFocusableInTouchMode(true);
             requestFocus();
+        } else {
+            if (mPopup != null) {
+                mPopup.dismiss();
+            }
         }
     }
 
@@ -325,6 +330,7 @@
             setVisibility(View.GONE);
         }
         if (mBar != null) {
+            // This will indirectly cause show(false, ...) to get called
             mBar.animateCollapse();
         }
     }
@@ -729,10 +735,20 @@
         getContext().startActivity(intent);
     }
 
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mPopup != null) {
+            return true;
+        } else {
+            return super.onInterceptTouchEvent(ev);
+        }
+    }
+
     public void handleLongPress(
             final View selectedView, final View anchorView, final View thumbnailView) {
         thumbnailView.setSelected(true);
-        PopupMenu popup = new PopupMenu(mContext, anchorView == null ? selectedView : anchorView);
+        final PopupMenu popup =
+            new PopupMenu(mContext, anchorView == null ? selectedView : anchorView);
+        mPopup = popup;
         popup.getMenuInflater().inflate(R.menu.recent_popup_menu, popup.getMenu());
         popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
             public boolean onMenuItemClick(MenuItem item) {
@@ -756,6 +772,7 @@
         popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
             public void onDismiss(PopupMenu menu) {
                 thumbnailView.setSelected(false);
+                mPopup = null;
             }
         });
         popup.show();
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
index 5529d0c..6bd1826 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
@@ -37,15 +37,11 @@
     public static final boolean OPTIMIZE_SW_RENDERED_RECENTS = true;
     public static final boolean USE_DARK_FADE_IN_HW_ACCELERATED_MODE = true;
     private View mScrollView;
-    private LinearLayout mLinearLayout;
     private RecentsCallback mCallback;
 
-    private boolean mShowBackground = false;
     private int mFadingEdgeLength;
-    private Drawable.ConstantState mBackgroundDrawable;
     private Context mContext;
     private boolean mIsVertical;
-    private boolean mFirstTime = true;
     private boolean mSoftwareRendered = false;
     private boolean mAttachedToWindow = false;
 
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 6833a57..3db4601 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -172,6 +172,7 @@
             pw.println(prefix + "  deleteIntent=" + notification.deleteIntent);
             pw.println(prefix + "  tickerText=" + notification.tickerText);
             pw.println(prefix + "  contentView=" + notification.contentView);
+            pw.println(prefix + "  uid=" + uid);
             pw.println(prefix + "  defaults=0x" + Integer.toHexString(notification.defaults));
             pw.println(prefix + "  flags=0x" + Integer.toHexString(notification.flags));
             pw.println(prefix + "  sound=" + notification.sound);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ab4012f..a6fbdd7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -904,10 +904,15 @@
                             null, null, 0, null, null, null,
                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
 
-                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
-                            mContext, proc, (ActivityRecord)data.get("activity"));
-                    d.show();
-                    proc.anrDialog = d;
+                    if (mShowDialogs) {
+                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
+                                mContext, proc, (ActivityRecord)data.get("activity"));
+                        d.show();
+                        proc.anrDialog = d;
+                    } else {
+                        // Just kill the app if there is no dialog to be shown.
+                        killAppAtUsersRequest(proc, null);
+                    }
                 }
                 
                 ensureBootCompleted();
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index dd6c426..16ddd91 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -35,6 +35,7 @@
 
 #include <gui/ISensorServer.h>
 #include <gui/ISensorEventConnection.h>
+#include <gui/SensorEventQueue.h>
 
 #include <hardware/sensors.h>
 
@@ -587,10 +588,9 @@
         count = numEvents;
     }
 
-    if (count == 0)
-        return 0;
-
-    ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
+    // NOTE: ASensorEvent and sensors_event_t are the same type
+    ssize_t size = SensorEventQueue::write(mChannel,
+            reinterpret_cast<ASensorEvent const*>(scratch), count);
     if (size == -EAGAIN) {
         // the destination doesn't accept events anymore, it's probably
         // full. For now, we just drop the events on the floor.
@@ -598,9 +598,6 @@
         return size;
     }
 
-    //ALOGE_IF(size<0, "dropping %d events on the floor (%s)",
-    //        count, strerror(-size));
-
     return size < 0 ? status_t(size) : status_t(NO_ERROR);
 }
 
diff --git a/tests/BiDiTests/AndroidManifest.xml b/tests/BiDiTests/AndroidManifest.xml
index c60edd8..4aead814 100644
--- a/tests/BiDiTests/AndroidManifest.xml
+++ b/tests/BiDiTests/AndroidManifest.xml
@@ -19,7 +19,9 @@
     android:versionCode="1"
     android:versionName="1.0">
 
-    <application android:label="BiDiTests" android:hardwareAccelerated="true">
+    <application android:label="BiDiTests"
+                 android:hardwareAccelerated="true"
+                 android:supportsRtl="true" >
 
         <activity android:name=".BiDiTestActivity"
             android:windowSoftInputMode="stateAlwaysHidden">
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index f4c0841..3775f9f 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -42,6 +42,15 @@
         </activity>
 
         <activity
+                android:name="DatePickerActivity"
+                android:label="_DatePicker">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="ClipRegionActivity"
                 android:label="_ClipRegion">
             <intent-filter>
@@ -657,5 +666,14 @@
             </intent-filter>
         </activity>
 
+        <activity
+                android:name="ViewPropertyAlphaActivity"
+                android:label="_ViewPropAlpha">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
     </application>
 </manifest>
diff --git a/tests/HwAccelerationTest/res/layout/date_picker.xml b/tests/HwAccelerationTest/res/layout/date_picker.xml
new file mode 100644
index 0000000..742a03b
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/date_picker.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- Layout of date picker-->
+
+<!-- The width of this container is manually set a little bigger than the one of the children
+     contained in it. This helps to prevent rounding errors when toggling the "Show year" option -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_gravity="center_horizontal"
+              android:layout_width="270dip"
+              android:layout_height="wrap_content">
+
+    <CheckBox
+            android:id="@+id/yearToggle"
+            android:text="Provide a year"
+            android:paddingTop="5dip"
+            android:paddingBottom="5dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:layout_gravity="center_horizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    <!-- Warning: everything within the parent is removed and re-ordered depending
+         on the date format selected by the user. -->
+    <LinearLayout
+            android:id="@+id/parent"
+            android:orientation="horizontal"
+            android:layout_gravity="center_horizontal"
+            android:animateLayoutChanges="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+
+        <!-- Month -->
+        <NumberPicker
+                android:id="@+id/month"
+                android:layout_width="80dip"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="1dip"
+                android:layout_marginRight="1dip"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                />
+
+        <!-- Day -->
+        <NumberPicker
+                android:id="@+id/day"
+                android:layout_width="80dip"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="1dip"
+                android:layout_marginRight="1dip"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                />
+
+        <!-- Year -->
+        <NumberPicker
+                android:id="@+id/year"
+                android:layout_width="95dip"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="1dip"
+                android:layout_marginRight="1dip"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                />
+    </LinearLayout>
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/res/layout/view_properties.xml b/tests/HwAccelerationTest/res/layout/view_properties.xml
new file mode 100644
index 0000000..d7ed8192
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/view_properties.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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:id="@+id/container">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Invalidate"
+            android:id="@+id/invalidateButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Button"
+            android:id="@+id/button"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Some text"
+            android:id="@+id/textview"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/spantext"/>
+    <EditText
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Edit text"
+            android:id="@+id/edittext"/>
+    <EditText
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Selected text"
+            android:id="@+id/selectedtext"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Some text"
+            android:background="#00ff00"
+            android:id="@+id/textviewbackground"/>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/icon"
+            android:id="@+id/imageview"/>
+    <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:id="@+id/layout">
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Button"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Some text"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Some text"
+                android:background="#00ff00"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java
new file mode 100644
index 0000000..db247e3
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.test.hwui;
+
+import android.annotation.Widget;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.NumberPicker;
+
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+/**
+ * A view for selecting a month / year / day based on a calendar like layout.
+ *
+ * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
+ * tutorial</a>.</p>
+ *
+ * For a dialog using this view, see {@link android.app.DatePickerDialog}.
+ */
+@Widget
+public class DatePicker extends FrameLayout {
+
+    private static final int DEFAULT_START_YEAR = 1900;
+    private static final int DEFAULT_END_YEAR = 2100;
+
+    /* UI Components */
+    private final CheckBox mYearToggle;
+    private final NumberPicker mDayPicker;
+    private final NumberPicker mMonthPicker;
+    private final NumberPicker mYearPicker;
+
+    /**
+     * How we notify users the date has changed.
+     */
+    private OnDateChangedListener mOnDateChangedListener;
+
+    private int mDay;
+    private int mMonth;
+    private int mYear;
+    private boolean mYearOptional = true;
+    private boolean mHasYear;
+
+    /**
+     * The callback used to indicate the user changes the date.
+     */
+    public interface OnDateChangedListener {
+
+        /**
+         * @param view The view associated with this listener.
+         * @param year The year that was set.
+         * @param monthOfYear The month that was set (0-11) for compatibility
+         *  with {@link java.util.Calendar}.
+         * @param dayOfMonth The day of the month that was set.
+         */
+        void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
+    }
+
+    public DatePicker(Context context) {
+        this(context, null);
+    }
+
+    public DatePicker(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    @SuppressWarnings("deprecation")
+    public DatePicker(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        ContextThemeWrapper themed = new ContextThemeWrapper(context,
+                com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert);
+        LayoutInflater inflater = (LayoutInflater) themed.getSystemService(
+                        Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(R.layout.date_picker, this, true);
+
+        mDayPicker = (NumberPicker) findViewById(R.id.day);
+        mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
+        mDayPicker.setOnLongPressUpdateInterval(100);
+        mDayPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                mDay = newVal;
+                notifyDateChanged();
+            }
+        });
+        mMonthPicker = (NumberPicker) findViewById(R.id.month);
+        mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
+        DateFormatSymbols dfs = new DateFormatSymbols();
+        String[] months = dfs.getShortMonths();
+
+        /*
+         * If the user is in a locale where the month names are numeric,
+         * use just the number instead of the "month" character for
+         * consistency with the other fields.
+         */
+        if (months[0].startsWith("1")) {
+            for (int i = 0; i < months.length; i++) {
+                months[i] = String.valueOf(i + 1);
+            }
+            mMonthPicker.setMinValue(1);
+            mMonthPicker.setMaxValue(12);
+        } else {
+            mMonthPicker.setMinValue(1);
+            mMonthPicker.setMaxValue(12);
+            mMonthPicker.setDisplayedValues(months);
+        }
+
+        mMonthPicker.setOnLongPressUpdateInterval(200);
+        mMonthPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+
+                /* We display the month 1-12 but store it 0-11 so always
+                 * subtract by one to ensure our internal state is always 0-11
+                 */
+                mMonth = newVal - 1;
+                // Adjust max day of the month
+                adjustMaxDay();
+                notifyDateChanged();
+                updateDaySpinner();
+            }
+        });
+        mYearPicker = (NumberPicker) findViewById(R.id.year);
+        mYearPicker.setOnLongPressUpdateInterval(100);
+        mYearPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                mYear = newVal;
+                // Adjust max day for leap years if needed
+                adjustMaxDay();
+                notifyDateChanged();
+                updateDaySpinner();
+            }
+        });
+
+        mYearToggle = (CheckBox) findViewById(R.id.yearToggle);
+        mYearToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                mHasYear = isChecked;
+                adjustMaxDay();
+                notifyDateChanged();
+                updateSpinners();
+            }
+        });
+
+        // attributes
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.DatePicker);
+
+        int mStartYear =
+                a.getInt(com.android.internal.R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
+        int mEndYear =
+                a.getInt(com.android.internal.R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
+        mYearPicker.setMinValue(mStartYear);
+        mYearPicker.setMaxValue(mEndYear);
+
+        a.recycle();
+
+        // initialize to current date
+        Calendar cal = Calendar.getInstance();
+        init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
+
+        // re-order the number pickers to match the current date format
+        reorderPickers(months);
+
+        if (!isEnabled()) {
+            setEnabled(false);
+        }
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        mDayPicker.setEnabled(enabled);
+        mMonthPicker.setEnabled(enabled);
+        mYearPicker.setEnabled(enabled);
+    }
+
+    private void reorderPickers(String[] months) {
+        java.text.DateFormat format;
+        String order;
+
+        /*
+         * If the user is in a locale where the medium date format is
+         * still numeric (Japanese and Czech, for example), respect
+         * the date format order setting.  Otherwise, use the order
+         * that the locale says is appropriate for a spelled-out date.
+         */
+
+        if (months[0].startsWith("1")) {
+            format = DateFormat.getDateFormat(getContext());
+        } else {
+            format = DateFormat.getMediumDateFormat(getContext());
+        }
+
+        if (format instanceof SimpleDateFormat) {
+            order = ((SimpleDateFormat) format).toPattern();
+        } else {
+            // Shouldn't happen, but just in case.
+            order = new String(DateFormat.getDateFormatOrder(getContext()));
+        }
+
+        /* Remove the 3 pickers from their parent and then add them back in the
+         * required order.
+         */
+        LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
+        parent.removeAllViews();
+
+        boolean quoted = false;
+        boolean didDay = false, didMonth = false, didYear = false;
+
+        for (int i = 0; i < order.length(); i++) {
+            char c = order.charAt(i);
+
+            if (c == '\'') {
+                quoted = !quoted;
+            }
+
+            if (!quoted) {
+                if (c == DateFormat.DATE && !didDay) {
+                    parent.addView(mDayPicker);
+                    didDay = true;
+                } else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) {
+                    parent.addView(mMonthPicker);
+                    didMonth = true;
+                } else if (c == DateFormat.YEAR && !didYear) {
+                    parent.addView (mYearPicker);
+                    didYear = true;
+                }
+            }
+        }
+
+        // Shouldn't happen, but just in case.
+        if (!didMonth) {
+            parent.addView(mMonthPicker);
+        }
+        if (!didDay) {
+            parent.addView(mDayPicker);
+        }
+        if (!didYear) {
+            parent.addView(mYearPicker);
+        }
+    }
+
+    public void updateDate(int year, int monthOfYear, int dayOfMonth) {
+        if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) {
+            mYear = (mYearOptional && year == 0) ? getCurrentYear() : year;
+            mMonth = monthOfYear;
+            mDay = dayOfMonth;
+            updateSpinners();
+            reorderPickers(new DateFormatSymbols().getShortMonths());
+            notifyDateChanged();
+        }
+    }
+
+    private static int getCurrentYear() {
+        return Calendar.getInstance().get(Calendar.YEAR);
+    }
+
+    private static class SavedState extends BaseSavedState {
+
+        private final int mYear;
+        private final int mMonth;
+        private final int mDay;
+        private final boolean mHasYear;
+        private final boolean mYearOptional;
+
+        /**
+         * Constructor called from {@link DatePicker#onSaveInstanceState()}
+         */
+        private SavedState(Parcelable superState, int year, int month, int day, boolean hasYear,
+                boolean yearOptional) {
+            super(superState);
+            mYear = year;
+            mMonth = month;
+            mDay = day;
+            mHasYear = hasYear;
+            mYearOptional = yearOptional;
+        }
+
+        /**
+         * Constructor called from {@link #CREATOR}
+         */
+        private SavedState(Parcel in) {
+            super(in);
+            mYear = in.readInt();
+            mMonth = in.readInt();
+            mDay = in.readInt();
+            mHasYear = in.readInt() != 0;
+            mYearOptional = in.readInt() != 0;
+        }
+
+        public int getYear() {
+            return mYear;
+        }
+
+        public int getMonth() {
+            return mMonth;
+        }
+
+        public int getDay() {
+            return mDay;
+        }
+
+        public boolean hasYear() {
+            return mHasYear;
+        }
+
+        public boolean isYearOptional() {
+            return mYearOptional;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mYear);
+            dest.writeInt(mMonth);
+            dest.writeInt(mDay);
+            dest.writeInt(mHasYear ? 1 : 0);
+            dest.writeInt(mYearOptional ? 1 : 0);
+        }
+
+        @SuppressWarnings("unused")
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Creator<SavedState>() {
+
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+
+
+    /**
+     * Override so we are in complete control of save / restore for this widget.
+     */
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        dispatchThawSelfOnly(container);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+
+        return new SavedState(superState, mYear, mMonth, mDay, mHasYear, mYearOptional);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mYear = ss.getYear();
+        mMonth = ss.getMonth();
+        mDay = ss.getDay();
+        mHasYear = ss.hasYear();
+        mYearOptional = ss.isYearOptional();
+        updateSpinners();
+    }
+
+    /**
+     * Initialize the state.
+     * @param year The initial year.
+     * @param monthOfYear The initial month.
+     * @param dayOfMonth The initial day of the month.
+     * @param onDateChangedListener How user is notified date is changed by user, can be null.
+     */
+    public void init(int year, int monthOfYear, int dayOfMonth,
+            OnDateChangedListener onDateChangedListener) {
+        init(year, monthOfYear, dayOfMonth, false, onDateChangedListener);
+    }
+
+    /**
+     * Initialize the state.
+     * @param year The initial year or 0 if no year has been specified
+     * @param monthOfYear The initial month.
+     * @param dayOfMonth The initial day of the month.
+     * @param yearOptional True if the user can toggle the year
+     * @param onDateChangedListener How user is notified date is changed by user, can be null.
+     */
+    public void init(int year, int monthOfYear, int dayOfMonth, boolean yearOptional,
+            OnDateChangedListener onDateChangedListener) {
+        mYear = (yearOptional && year == 0) ? getCurrentYear() : year;
+        mMonth = monthOfYear;
+        mDay = dayOfMonth;
+        mYearOptional = yearOptional;
+        mHasYear = !yearOptional || (year != 0);
+        mOnDateChangedListener = onDateChangedListener;
+        updateSpinners();
+    }
+
+    private void updateSpinners() {
+        updateDaySpinner();
+        mYearToggle.setChecked(mHasYear);
+        mYearToggle.setVisibility(mYearOptional ? View.VISIBLE : View.GONE);
+        mYearPicker.setValue(mYear);
+        mYearPicker.setVisibility(mHasYear ? View.VISIBLE : View.GONE);
+
+        /* The month display uses 1-12 but our internal state stores it
+         * 0-11 so add one when setting the display.
+         */
+        mMonthPicker.setValue(mMonth + 1);
+    }
+
+    private void updateDaySpinner() {
+        Calendar cal = Calendar.getInstance();
+        // if year was not set, use 2000 as it was a leap year
+        cal.set(mHasYear ? mYear : 2000, mMonth, 1);
+        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+        mDayPicker.setMinValue(1);
+        mDayPicker.setMaxValue(max);
+        mDayPicker.setValue(mDay);
+    }
+
+    public int getYear() {
+        return (mYearOptional && !mHasYear) ? 0 : mYear;
+    }
+
+    public int getMonth() {
+        return mMonth;
+    }
+
+    public int getDayOfMonth() {
+        return mDay;
+    }
+
+    private void adjustMaxDay(){
+        Calendar cal = Calendar.getInstance();
+        // if year was not set, use 2000 as it was a leap year
+        cal.set(Calendar.YEAR, mHasYear ? mYear : 2000);
+        cal.set(Calendar.MONTH, mMonth);
+        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+        if (mDay > max) {
+            mDay = max;
+        }
+    }
+
+    private void notifyDateChanged() {
+        if (mOnDateChangedListener != null) {
+            int year = (mYearOptional && !mHasYear) ? 0 : mYear;
+            mOnDateChangedListener.onDateChanged(DatePicker.this, year, mMonth, mDay);
+        }
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java
new file mode 100644
index 0000000..5482ee2
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class DatePickerActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        DatePicker picker = new DatePicker(this);
+        picker.init(2012, 3, 3, true, new DatePicker.OnDateChangedListener() {
+            @Override
+            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
+            }
+        });
+        setContentView(picker);
+        getWindow().setBackgroundDrawable(new ColorDrawable(0xffffffff));
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java
new file mode 100644
index 0000000..738801d
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.test.hwui;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.style.BackgroundColorSpan;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.ImageSpan;
+import android.text.style.SuggestionSpan;
+import android.text.style.UnderlineSpan;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class ViewPropertyAlphaActivity extends Activity {
+    
+    MyView myViewAlphaDefault, myViewAlphaHandled;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.view_properties);
+
+        getWindow().getDecorView().postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                startAnim(R.id.button);
+                startAnim(R.id.textview);
+                startAnim(R.id.spantext);
+                startAnim(R.id.edittext);
+                startAnim(R.id.selectedtext);
+                startAnim(R.id.textviewbackground);
+                startAnim(R.id.layout);
+                startAnim(R.id.imageview);
+                startAnim(myViewAlphaDefault);
+                startAnim(myViewAlphaHandled);
+                EditText selectedText = (EditText) findViewById(R.id.selectedtext);
+                selectedText.setSelection(3, 8);
+            }
+        }, 2000);
+        
+        Button invalidator = (Button) findViewById(R.id.invalidateButton);
+        invalidator.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                findViewById(R.id.textview).invalidate();
+                findViewById(R.id.spantext).invalidate();
+            }
+        });
+
+        TextView textView = (TextView) findViewById(R.id.spantext);
+        if (textView != null) {
+            SpannableStringBuilder text =
+                    new SpannableStringBuilder("Now this is a short text message with spans");
+
+            text.setSpan(new BackgroundColorSpan(Color.RED), 0, 3,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            text.setSpan(new ForegroundColorSpan(Color.BLUE), 4, 9,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            text.setSpan(new SuggestionSpan(this, new String[]{"longer"}, 3), 11, 16,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            text.setSpan(new UnderlineSpan(), 17, 20,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            text.setSpan(new ImageSpan(this, R.drawable.icon), 21, 22,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+            textView.setText(text);
+        }
+        
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        myViewAlphaDefault = new MyView(this, false);
+        myViewAlphaDefault.setLayoutParams(new LinearLayout.LayoutParams(75, 75));
+        container.addView(myViewAlphaDefault);
+        myViewAlphaHandled = new MyView(this, true);
+        myViewAlphaHandled.setLayoutParams(new LinearLayout.LayoutParams(75, 75));
+        container.addView(myViewAlphaHandled);
+    }
+
+    private void startAnim(View target) {
+        ObjectAnimator anim = ObjectAnimator.ofFloat(target, View.ALPHA, 0);
+        anim.setRepeatCount(ValueAnimator.INFINITE);
+        anim.setRepeatMode(ValueAnimator.REVERSE);
+        anim.setDuration(1000);
+        anim.start();
+    }
+    private void startAnim(int id) {
+        startAnim(findViewById(id));
+    }
+    
+    private static class MyView extends View {
+        private int mMyAlpha = 255;
+        private boolean mHandleAlpha;
+        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        
+        private MyView(Context context, boolean handleAlpha) {
+            super(context);
+            mHandleAlpha = handleAlpha;
+            mPaint.setColor(Color.RED);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            if (mHandleAlpha) {
+                mPaint.setAlpha(mMyAlpha);
+            }
+            canvas.drawCircle(30, 30, 30, mPaint);
+        }
+
+        @Override
+        protected boolean onSetAlpha(int alpha) {
+            if (mHandleAlpha) {
+                mMyAlpha = alpha;
+                return true;
+            }
+            return super.onSetAlpha(alpha);
+        }
+    }
+
+}