Merge "SurfaceTexture: update API docs"
diff --git a/api/16.txt b/api/16.txt
index de99eee..0e3a140 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -15190,11 +15190,11 @@
     method public abstract void released();
   }
 
-  public class Vibrator {
-    method public void cancel();
-    method public boolean hasVibrator();
-    method public void vibrate(long);
-    method public void vibrate(long[], int);
+  public abstract class Vibrator {
+    method public abstract void cancel();
+    method public abstract boolean hasVibrator();
+    method public abstract void vibrate(long);
+    method public abstract void vibrate(long[], int);
   }
 
   public class WorkSource implements android.os.Parcelable {
diff --git a/api/current.txt b/api/current.txt
index 5304e00..d94adc5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4833,6 +4833,7 @@
     method public android.content.ClipDescription getDescription();
     method public android.content.ClipData.Item getItemAt(int);
     method public int getItemCount();
+    method public static android.content.ClipData newHtmlText(java.lang.CharSequence, java.lang.CharSequence, java.lang.String);
     method public static android.content.ClipData newIntent(java.lang.CharSequence, android.content.Intent);
     method public static android.content.ClipData newPlainText(java.lang.CharSequence, java.lang.CharSequence);
     method public static android.content.ClipData newRawUri(java.lang.CharSequence, android.net.Uri);
@@ -4843,10 +4844,15 @@
 
   public static class ClipData.Item {
     ctor public ClipData.Item(java.lang.CharSequence);
+    ctor public ClipData.Item(java.lang.CharSequence, java.lang.String);
     ctor public ClipData.Item(android.content.Intent);
     ctor public ClipData.Item(android.net.Uri);
     ctor public ClipData.Item(java.lang.CharSequence, android.content.Intent, android.net.Uri);
+    ctor public ClipData.Item(java.lang.CharSequence, java.lang.String, android.content.Intent, android.net.Uri);
+    method public java.lang.String coerceToHtmlText(android.content.Context);
+    method public java.lang.CharSequence coerceToStyledText(android.content.Context);
     method public java.lang.CharSequence coerceToText(android.content.Context);
+    method public java.lang.String getHtmlText();
     method public android.content.Intent getIntent();
     method public java.lang.CharSequence getText();
     method public android.net.Uri getUri();
@@ -4864,6 +4870,7 @@
     method public boolean hasMimeType(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
     field public static final java.lang.String MIMETYPE_TEXT_URILIST = "text/uri-list";
@@ -5701,6 +5708,7 @@
     field public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; // 0x0
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
+    field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
     field public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT";
@@ -12905,6 +12913,8 @@
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
+    method public void setBeamPushUris(android.net.Uri[], android.app.Activity);
+    method public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
     method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
     method public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
     method public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
@@ -12916,6 +12926,10 @@
     field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
   }
 
+  public static abstract interface NfcAdapter.CreateBeamUrisCallback {
+    method public abstract android.net.Uri[] createBeamUris(android.nfc.NfcEvent);
+  }
+
   public static abstract interface NfcAdapter.CreateNdefMessageCallback {
     method public abstract android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent);
   }
@@ -15500,11 +15514,11 @@
     ctor public TransactionTooLargeException();
   }
 
-  public class Vibrator {
-    method public void cancel();
-    method public boolean hasVibrator();
-    method public void vibrate(long);
-    method public void vibrate(long[], int);
+  public abstract class Vibrator {
+    method public abstract void cancel();
+    method public abstract boolean hasVibrator();
+    method public abstract void vibrate(long);
+    method public abstract void vibrate(long[], int);
   }
 
   public class WorkSource implements android.os.Parcelable {
@@ -16944,6 +16958,7 @@
 
   public static final class ContactsContract.DataUsageFeedback {
     ctor public ContactsContract.DataUsageFeedback();
+    field public static final android.net.Uri DELETE_USAGE_URI;
     field public static final android.net.Uri FEEDBACK_URI;
     field public static final java.lang.String USAGE_TYPE = "type";
     field public static final java.lang.String USAGE_TYPE_CALL = "call";
@@ -20399,6 +20414,7 @@
   }
 
   public class Html {
+    method public static java.lang.String escapeHtml(java.lang.CharSequence);
     method public static android.text.Spanned fromHtml(java.lang.String);
     method public static android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
     method public static java.lang.String toHtml(android.text.Spanned);
@@ -22346,6 +22362,7 @@
     method public java.util.List<android.view.InputDevice.MotionRange> getMotionRanges();
     method public java.lang.String getName();
     method public int getSources();
+    method public android.os.Vibrator getVibrator();
     method public boolean isVirtual();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 138a88f..0645aa9 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -82,7 +82,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserId;
-import android.os.Vibrator;
+import android.os.SystemVibrator;
 import android.os.storage.StorageManager;
 import android.telephony.TelephonyManager;
 import android.content.ClipboardManager;
@@ -455,7 +455,7 @@
 
         registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
-                    return new Vibrator();
+                    return new SystemVibrator();
                 }});
 
         registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index a655dd4..1866830 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -21,7 +21,12 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.Html;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
 import android.text.TextUtils;
+import android.text.style.URLSpan;
 import android.util.Log;
 
 import java.io.FileInputStream;
@@ -144,6 +149,8 @@
 public class ClipData implements Parcelable {
     static final String[] MIMETYPES_TEXT_PLAIN = new String[] {
         ClipDescription.MIMETYPE_TEXT_PLAIN };
+    static final String[] MIMETYPES_TEXT_HTML = new String[] {
+        ClipDescription.MIMETYPE_TEXT_HTML };
     static final String[] MIMETYPES_TEXT_URILIST = new String[] {
         ClipDescription.MIMETYPE_TEXT_URILIST };
     static final String[] MIMETYPES_TEXT_INTENT = new String[] {
@@ -176,6 +183,7 @@
      */
     public static class Item {
         final CharSequence mText;
+        final String mHtmlText;
         final Intent mIntent;
         final Uri mUri;
 
@@ -184,6 +192,20 @@
          */
         public Item(CharSequence text) {
             mText = text;
+            mHtmlText = null;
+            mIntent = null;
+            mUri = null;
+        }
+
+        /**
+         * Create an Item consisting of a single block of (possibly styled) text,
+         * with an alternative HTML formatted representation.  You <em>must</em>
+         * supply a plain text representation in addition to HTML text; coercion
+         * will not be done from HTML formated text into plain text.
+         */
+        public Item(CharSequence text, String htmlText) {
+            mText = text;
+            mHtmlText = htmlText;
             mIntent = null;
             mUri = null;
         }
@@ -193,6 +215,7 @@
          */
         public Item(Intent intent) {
             mText = null;
+            mHtmlText = null;
             mIntent = intent;
             mUri = null;
         }
@@ -202,16 +225,35 @@
          */
         public Item(Uri uri) {
             mText = null;
+            mHtmlText = null;
             mIntent = null;
             mUri = uri;
         }
 
         /**
          * Create a complex Item, containing multiple representations of
-         * text, intent, and/or URI.
+         * text, Intent, and/or URI.
          */
         public Item(CharSequence text, Intent intent, Uri uri) {
             mText = text;
+            mHtmlText = null;
+            mIntent = intent;
+            mUri = uri;
+        }
+
+        /**
+         * Create a complex Item, containing multiple representations of
+         * text, HTML text, Intent, and/or URI.  If providing HTML text, you
+         * <em>must</em> supply a plain text representation as well; coercion
+         * will not be done from HTML formated text into plain text.
+         */
+        public Item(CharSequence text, String htmlText, Intent intent, Uri uri) {
+            if (htmlText != null && text == null) {
+                throw new IllegalArgumentException(
+                        "Plain text must be supplied if HTML text is supplied");
+            }
+            mText = text;
+            mHtmlText = htmlText;
             mIntent = intent;
             mUri = uri;
         }
@@ -224,6 +266,13 @@
         }
 
         /**
+         * Retrieve the raw HTML text contained in this Item.
+         */
+        public String getHtmlText() {
+            return mHtmlText;
+        }
+
+        /**
          * Retrieve the raw Intent contained in this Item.
          */
         public Intent getIntent() {
@@ -250,7 +299,7 @@
          * the content provider does not supply a text representation, return
          * the raw URI as a string.
          * <li> If {@link #getIntent} is non-null, convert that to an intent:
-         * URI and returnit.
+         * URI and return it.
          * <li> Otherwise, return an empty string.
          * </ul>
          *
@@ -261,12 +310,14 @@
 //BEGIN_INCLUDE(coerceToText)
         public CharSequence coerceToText(Context context) {
             // If this Item has an explicit textual value, simply return that.
-            if (mText != null) {
-                return mText;
+            CharSequence text = getText();
+            if (text != null) {
+                return text;
             }
 
             // If this Item has a URI value, try using that.
-            if (mUri != null) {
+            Uri uri = getUri();
+            if (uri != null) {
 
                 // First see if the URI can be opened as a plain text stream
                 // (of any sub-type).  If so, this is the best textual
@@ -275,7 +326,7 @@
                 try {
                     // Ask for a stream of the desired type.
                     AssetFileDescriptor descr = context.getContentResolver()
-                            .openTypedAssetFileDescriptor(mUri, "text/*", null);
+                            .openTypedAssetFileDescriptor(uri, "text/*", null);
                     stream = descr.createInputStream();
                     InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
 
@@ -308,13 +359,14 @@
 
                 // If we couldn't open the URI as a stream, then the URI itself
                 // probably serves fairly well as a textual representation.
-                return mUri.toString();
+                return uri.toString();
             }
 
             // Finally, if all we have is an Intent, then we can just turn that
             // into text.  Not the most user-friendly thing, but it's something.
-            if (mIntent != null) {
-                return mIntent.toUri(Intent.URI_INTENT_SCHEME);
+            Intent intent = getIntent();
+            if (intent != null) {
+                return intent.toUri(Intent.URI_INTENT_SCHEME);
             }
 
             // Shouldn't get here, but just in case...
@@ -322,6 +374,210 @@
         }
 //END_INCLUDE(coerceToText)
 
+        /**
+         * Like {@link #coerceToHtmlText(Context)}, but any text that would
+         * be returned as HTML formatting will be returned as text with
+         * style spans.
+         * @param context The caller's Context, from which its ContentResolver
+         * and other things can be retrieved.
+         * @return Returns the item's textual representation.
+         */
+        public CharSequence coerceToStyledText(Context context) {
+            CharSequence text = getText();
+            if (text instanceof Spanned) {
+                return text;
+            }
+            String htmlText = getHtmlText();
+            if (htmlText != null) {
+                try {
+                    CharSequence newText = Html.fromHtml(htmlText);
+                    if (newText != null) {
+                        return newText;
+                    }
+                } catch (RuntimeException e) {
+                    // If anything bad happens, we'll fall back on the plain text.
+                }
+            }
+
+            if (text != null) {
+                return text;
+            }
+            return coerceToHtmlOrStyledText(context, true);
+        }
+
+        /**
+         * Turn this item into HTML text, regardless of the type of data it
+         * actually contains.
+         *
+         * <p>The algorithm for deciding what text to return is:
+         * <ul>
+         * <li> If {@link #getHtmlText} is non-null, return that.
+         * <li> If {@link #getText} is non-null, return that, converting to
+         * valid HTML text.  If this text contains style spans,
+         * {@link Html#toHtml(Spanned) Html.toHtml(Spanned)} is used to
+         * convert them to HTML formatting.
+         * <li> If {@link #getUri} is non-null, try to retrieve its data
+         * as a text stream from its content provider.  If the provider can
+         * supply text/html data, that will be preferred and returned as-is.
+         * Otherwise, any text/* data will be returned and escaped to HTML.
+         * If it is not a content: URI or the content provider does not supply
+         * a text representation, HTML text containing a link to the URI
+         * will be returned.
+         * <li> If {@link #getIntent} is non-null, convert that to an intent:
+         * URI and return as an HTML link.
+         * <li> Otherwise, return an empty string.
+         * </ul>
+         *
+         * @param context The caller's Context, from which its ContentResolver
+         * and other things can be retrieved.
+         * @return Returns the item's representation as HTML text.
+         */
+        public String coerceToHtmlText(Context context) {
+            // If the item has an explicit HTML value, simply return that.
+            String htmlText = getHtmlText();
+            if (htmlText != null) {
+                return htmlText;
+            }
+
+            // If this Item has a plain text value, return it as HTML.
+            CharSequence text = getText();
+            if (text != null) {
+                if (text instanceof Spanned) {
+                    return Html.toHtml((Spanned)text);
+                }
+                return Html.escapeHtml(text);
+            }
+
+            text = coerceToHtmlOrStyledText(context, false);
+            return text != null ? text.toString() : null;
+        }
+
+        private CharSequence coerceToHtmlOrStyledText(Context context, boolean styled) {
+            // If this Item has a URI value, try using that.
+            if (mUri != null) {
+
+                // Check to see what data representations the content
+                // provider supports.  We would like HTML text, but if that
+                // is not possible we'll live with plan text.
+                String[] types = context.getContentResolver().getStreamTypes(mUri, "text/*");
+                boolean hasHtml = false;
+                boolean hasText = false;
+                if (types != null) {
+                    for (String type : types) {
+                        if ("text/html".equals(type)) {
+                            hasHtml = true;
+                        } else if (type.startsWith("text/")) {
+                            hasText = true;
+                        }
+                    }
+                }
+
+                // If the provider can serve data we can use, open and load it.
+                if (hasHtml || hasText) {
+                    FileInputStream stream = null;
+                    try {
+                        // Ask for a stream of the desired type.
+                        AssetFileDescriptor descr = context.getContentResolver()
+                                .openTypedAssetFileDescriptor(mUri,
+                                        hasHtml ? "text/html" : "text/plain", null);
+                        stream = descr.createInputStream();
+                        InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
+
+                        // Got it...  copy the stream into a local string and return it.
+                        StringBuilder builder = new StringBuilder(128);
+                        char[] buffer = new char[8192];
+                        int len;
+                        while ((len=reader.read(buffer)) > 0) {
+                            builder.append(buffer, 0, len);
+                        }
+                        String text = builder.toString();
+                        if (hasHtml) {
+                            if (styled) {
+                                // We loaded HTML formatted text and the caller
+                                // want styled text, convert it.
+                                try {
+                                    CharSequence newText = Html.fromHtml(text);
+                                    return newText != null ? newText : text;
+                                } catch (RuntimeException e) {
+                                    return text;
+                                }
+                            } else {
+                                // We loaded HTML formatted text and that is what
+                                // the caller wants, just return it.
+                                return text.toString();
+                            }
+                        }
+                        if (styled) {
+                            // We loaded plain text and the caller wants styled
+                            // text, that is all we have so return it.
+                            return text;
+                        } else {
+                            // We loaded plain text and the caller wants HTML
+                            // text, escape it for HTML.
+                            return Html.escapeHtml(text);
+                        }
+
+                    } catch (FileNotFoundException e) {
+                        // Unable to open content URI as text...  not really an
+                        // error, just something to ignore.
+
+                    } catch (IOException e) {
+                        // Something bad has happened.
+                        Log.w("ClippedData", "Failure loading text", e);
+                        return Html.escapeHtml(e.toString());
+
+                    } finally {
+                        if (stream != null) {
+                            try {
+                                stream.close();
+                            } catch (IOException e) {
+                            }
+                        }
+                    }
+                }
+
+                // If we couldn't open the URI as a stream, then we can build
+                // some HTML text with the URI itself.
+                // probably serves fairly well as a textual representation.
+                if (styled) {
+                    return uriToStyledText(mUri.toString());
+                } else {
+                    return uriToHtml(mUri.toString());
+                }
+            }
+
+            // Finally, if all we have is an Intent, then we can just turn that
+            // into text.  Not the most user-friendly thing, but it's something.
+            if (mIntent != null) {
+                if (styled) {
+                    return uriToStyledText(mIntent.toUri(Intent.URI_INTENT_SCHEME));
+                } else {
+                    return uriToHtml(mIntent.toUri(Intent.URI_INTENT_SCHEME));
+                }
+            }
+
+            // Shouldn't get here, but just in case...
+            return "";
+        }
+
+        private String uriToHtml(String uri) {
+            StringBuilder builder = new StringBuilder(256);
+            builder.append("<a href=\"");
+            builder.append(uri);
+            builder.append("\">");
+            builder.append(Html.escapeHtml(uri));
+            builder.append("</a>");
+            return builder.toString();
+        }
+
+        private CharSequence uriToStyledText(String uri) {
+            SpannableStringBuilder builder = new SpannableStringBuilder();
+            builder.append(uri);
+            builder.setSpan(new URLSpan(uri), 0, builder.length(),
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            return builder;
+        }
+
         @Override
         public String toString() {
             StringBuilder b = new StringBuilder(128);
@@ -335,7 +591,10 @@
 
         /** @hide */
         public void toShortString(StringBuilder b) {
-            if (mText != null) {
+            if (mHtmlText != null) {
+                b.append("H:");
+                b.append(mHtmlText);
+            } else if (mText != null) {
                 b.append("T:");
                 b.append(mText);
             } else if (mUri != null) {
@@ -409,6 +668,22 @@
     }
 
     /**
+     * Create a new ClipData holding data of the type
+     * {@link ClipDescription#MIMETYPE_TEXT_HTML}.
+     *
+     * @param label User-visible label for the clip data.
+     * @param text The text of clip as plain text, for receivers that don't
+     * handle HTML.  This is required.
+     * @param htmlText The actual HTML text in the clip.
+     * @return Returns a new ClipData containing the specified data.
+     */
+    static public ClipData newHtmlText(CharSequence label, CharSequence text,
+            String htmlText) {
+        Item item = new Item(text, htmlText);
+        return new ClipData(label, MIMETYPES_TEXT_HTML, item);
+    }
+
+    /**
      * Create a new ClipData holding an Intent with MIME type
      * {@link ClipDescription#MIMETYPE_TEXT_INTENT}.
      *
@@ -574,6 +849,7 @@
         for (int i=0; i<N; i++) {
             Item item = mItems.get(i);
             TextUtils.writeToParcel(item.mText, dest, flags);
+            dest.writeString(item.mHtmlText);
             if (item.mIntent != null) {
                 dest.writeInt(1);
                 item.mIntent.writeToParcel(dest, flags);
@@ -600,9 +876,10 @@
         final int N = in.readInt();
         for (int i=0; i<N; i++) {
             CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+            String htmlText = in.readString();
             Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null;
             Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null;
-            mItems.add(new Item(text, intent, uri));
+            mItems.add(new Item(text, htmlText, intent, uri));
         }
     }
 
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index c6b51ef..5cb6e77 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -41,6 +41,11 @@
     public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
 
     /**
+     * The MIME type for a clip holding HTML text.
+     */
+    public static final String MIMETYPE_TEXT_HTML = "text/html";
+
+    /**
      * The MIME type for a clip holding one or more URIs.  This should be
      * used for URIs that are meaningful to a user (such as an http: URI).
      * It should <em>not</em> be used for a content: URI that references some
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 2930998..722fdc6 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -248,7 +248,7 @@
      * @param mimeTypeFilter The desired MIME type.  This may be a pattern,
      * such as *\/*, to query for all available MIME types that match the
      * pattern.
-     * @return Returns an array of MIME type strings for all availablle
+     * @return Returns an array of MIME type strings for all available
      * data streams that match the given mimeTypeFilter.  If there are none,
      * null is returned.
      */
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 18d682d..19e4372 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -954,7 +954,18 @@
      * using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it
      * should be the MIME type of the data in EXTRA_STREAM.  Use {@literal *}/*
      * if the MIME type is unknown (this will only allow senders that can
-     * handle generic data streams).
+     * handle generic data streams).  If using {@link #EXTRA_TEXT}, you can
+     * also optionally supply {@link #EXTRA_HTML_TEXT} for clients to retrieve
+     * your text with HTML formatting.
+     * <p>
+     * As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}, the data
+     * being sent can be supplied through {@link #setClipData(ClipData)}.  This
+     * allows you to use {@link #FLAG_GRANT_READ_URI_PERMISSION} when sharing
+     * content: URIs and other advanced features of {@link ClipData}.  If
+     * using this approach, you still must supply the same data through the
+     * {@link #EXTRA_TEXT} or {@link #EXTRA_STREAM} fields described below
+     * for compatibility with old applications.  If you don't set a ClipData,
+     * it will be copied there for you when calling {@link Context#startActivity(Intent)}.
      * <p>
      * Optional standard extras, which may be interpreted by some recipients as
      * appropriate, are: {@link #EXTRA_EMAIL}, {@link #EXTRA_CC},
@@ -967,11 +978,13 @@
     /**
      * Activity Action: Deliver multiple data to someone else.
      * <p>
-     * Like ACTION_SEND, except the data is multiple.
+     * Like {@link #ACTION_SEND}, except the data is multiple.
      * <p>
      * Input: {@link #getType} is the MIME type of the data being sent.
      * get*ArrayListExtra can have either a {@link #EXTRA_TEXT} or {@link
-     * #EXTRA_STREAM} field, containing the data to be sent.
+     * #EXTRA_STREAM} field, containing the data to be sent.  If using
+     * {@link #EXTRA_TEXT}, you can also optionally supply {@link #EXTRA_HTML_TEXT}
+     * for clients to retrieve your text with HTML formatting.
      * <p>
      * Multiple types are supported, and receivers should handle mixed types
      * whenever possible. The right way for the receiver to check them is to
@@ -983,6 +996,15 @@
      * be image/jpg, but if you are sending image/jpg and image/png, then the
      * intent's type should be image/*.
      * <p>
+     * As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}, the data
+     * being sent can be supplied through {@link #setClipData(ClipData)}.  This
+     * allows you to use {@link #FLAG_GRANT_READ_URI_PERMISSION} when sharing
+     * content: URIs and other advanced features of {@link ClipData}.  If
+     * using this approach, you still must supply the same data through the
+     * {@link #EXTRA_TEXT} or {@link #EXTRA_STREAM} fields described below
+     * for compatibility with old applications.  If you don't set a ClipData,
+     * it will be copied there for you when calling {@link Context#startActivity(Intent)}.
+     * <p>
      * Optional standard extras, which may be interpreted by some recipients as
      * appropriate, are: {@link #EXTRA_EMAIL}, {@link #EXTRA_CC},
      * {@link #EXTRA_BCC}, {@link #EXTRA_SUBJECT}.
@@ -2501,6 +2523,14 @@
     public static final String EXTRA_TEXT = "android.intent.extra.TEXT";
 
     /**
+     * A constant String that is associated with the Intent, used with
+     * {@link #ACTION_SEND} to supply an alternative to {@link #EXTRA_TEXT}
+     * as HTML formatted text.  Note that you <em>must</em> also supply
+     * {@link #EXTRA_TEXT}.
+     */
+    public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+
+    /**
      * A content: URI holding a stream of data associated with the Intent,
      * used with {@link #ACTION_SEND} to supply the data being sent.
      */
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index ca8321f..3137947 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.IInputDevicesChangedListener;
+import android.os.IBinder;
 import android.view.InputDevice;
 import android.view.InputEvent;
 
@@ -46,4 +47,8 @@
 
     // Registers an input devices changed listener.
     void registerInputDevicesChangedListener(IInputDevicesChangedListener listener);
+
+    // Input device vibrator control.
+    void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token);
+    void cancelVibrate(int deviceId, IBinder token);
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 35c49a1..b39b823 100755
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -19,12 +19,14 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
@@ -587,6 +589,15 @@
     }
 
     /**
+     * Gets a vibrator service associated with an input device, assuming it has one.
+     * @return The vibrator, never null.
+     * @hide
+     */
+    public Vibrator getInputDeviceVibrator(int deviceId) {
+        return new InputDeviceVibrator(deviceId);
+    }
+
+    /**
      * Listens for changes in input devices.
      */
     public interface InputDeviceListener {
@@ -645,4 +656,45 @@
             }
         }
     }
+
+    private final class InputDeviceVibrator extends Vibrator {
+        private final int mDeviceId;
+        private final Binder mToken;
+
+        public InputDeviceVibrator(int deviceId) {
+            mDeviceId = deviceId;
+            mToken = new Binder();
+        }
+
+        @Override
+        public boolean hasVibrator() {
+            return true;
+        }
+
+        @Override
+        public void vibrate(long milliseconds) {
+            vibrate(new long[] { 0, milliseconds}, -1);
+        }
+
+        @Override
+        public void vibrate(long[] pattern, int repeat) {
+            if (repeat >= pattern.length) {
+                throw new ArrayIndexOutOfBoundsException();
+            }
+            try {
+                mIm.vibrate(mDeviceId, pattern, repeat, mToken);
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Failed to vibrate.", ex);
+            }
+        }
+
+        @Override
+        public void cancel() {
+            try {
+                mIm.cancelVibrate(mDeviceId, mToken);
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Failed to cancel vibration.", ex);
+            }
+        }
+    }
 }
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/INdefPushCallback.aidl
index 4e79822..1c6d5d0 100644
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ b/core/java/android/nfc/INdefPushCallback.aidl
@@ -25,7 +25,6 @@
 interface INdefPushCallback
 {
     NdefMessage createMessage();
-    Uri getUri();
-    String getMimeType();
+    Uri[] getUris();
     void onNdefPushComplete();
 }
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index f80dae4..7ffa575 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -108,8 +108,8 @@
         NdefMessage ndefMessage = null;  // static NDEF message
         NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
         NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
-        Uri uri = null;
-        String mimeType = null;
+        NfcAdapter.CreateBeamUrisCallback uriCallback = null;
+        Uri[] uris = null;
         public NfcActivityState(Activity activity) {
             if (activity.getWindow().isDestroyed()) {
                 throw new IllegalStateException("activity is already destroyed");
@@ -128,14 +128,19 @@
             ndefMessage = null;
             ndefMessageCallback = null;
             onNdefPushCompleteCallback = null;
-            uri = null;
-            mimeType = null;
+            uriCallback = null;
+            uris = null;
         }
         @Override
         public String toString() {
             StringBuilder s = new StringBuilder("[").append(" ");
             s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
-            s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
+            s.append(uriCallback).append(" ");
+            if (uris != null) {
+                for (Uri uri : uris) {
+                    s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
+                }
+            }
             return s.toString();
         }
     }
@@ -184,12 +189,25 @@
         mDefaultEvent = new NfcEvent(mAdapter);
     }
 
-    public void setNdefPushContentUri(Activity activity, String mimeType, Uri uri) {
+    public void setNdefPushContentUri(Activity activity, Uri[] uris) {
         boolean isResumed;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = getActivityState(activity);
-            state.uri = uri;
-            state.mimeType = mimeType;
+            state.uris = uris;
+            isResumed = state.resumed;
+        }
+        if (isResumed) {
+            requestNfcServiceCallback(true);
+        }
+    }
+
+
+    public void setNdefPushContentUriCallback(Activity activity,
+            NfcAdapter.CreateBeamUrisCallback callback) {
+        boolean isResumed;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = getActivityState(activity);
+            state.uriCallback = callback;
             isResumed = state.resumed;
         }
         if (isResumed) {
@@ -271,24 +289,22 @@
 
     /** Callback from NFC service, usually on binder thread */
     @Override
-    public Uri getUri() {
+    public Uri[] getUris() {
+        Uri[] uris;
+        NfcAdapter.CreateBeamUrisCallback callback;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = findResumedActivityState();
             if (state == null) return null;
-
-            return state.uri;
+            uris = state.uris;
+            callback = state.uriCallback;
+        }
+        if (callback != null) {
+            return callback.createBeamUris(mDefaultEvent);
+        } else {
+            return uris;
         }
     }
-    /** Callback from NFC service, usually on binder thread */
-    @Override
-    public String getMimeType() {
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findResumedActivityState();
-            if (state == null) return null;
 
-            return state.mimeType;
-        }
-    }
     /** Callback from NFC service, usually on binder thread */
     @Override
     public void onNdefPushComplete() {
@@ -358,4 +374,5 @@
             }
         }
     }
+
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 917751c..90f5bef 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -203,6 +203,27 @@
     /** @hide */
     public static final int STATE_TURNING_OFF = 4;
 
+    /** @hide */
+    public static final String ACTION_HANDOVER_TRANSFER_STARTED =
+            "android.nfc.action.HANDOVER_TRANSFER_STARTED";
+
+    /** @hide */
+    public static final String ACTION_HANDOVER_TRANSFER_DONE =
+            "android.nfc.action.HANDOVER_TRANSFER_DONE";
+
+    /** @hide */
+    public static final String EXTRA_HANDOVER_TRANSFER_STATUS =
+            "android.nfc.extra.HANDOVER_TRANSFER_STATUS";
+
+    /** @hide */
+    public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
+    /** @hide */
+    public static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
+
+    /** @hide */
+    public static final String EXTRA_HANDOVER_TRANSFER_URI =
+            "android.nfc.extra.HANDOVER_TRANSFER_URI";
+
     // Guarded by NfcAdapter.class
     static boolean sIsInitialized = false;
 
@@ -281,6 +302,12 @@
         public NdefMessage createNdefMessage(NfcEvent event);
     }
 
+
+    // TODO javadoc
+    public interface CreateBeamUrisCallback {
+        public Uri[] createBeamUris(NfcEvent event);
+    }
+
     /**
      * Helper to check if this device has FEATURE_NFC, but without using
      * a context.
@@ -556,16 +583,22 @@
         }
     }
 
-    //TODO: Consider a callback alternative
-    //TOOD: See if we get rid of mimeType
     //TODO: make sure NFC service has permission for URI
+    //TODO: see if we will eventually support multiple URIs
     //TODO: javadoc
-    /** @hide */
-    public void setBeamPushUri(String mimeType, Uri uri, Activity activity) {
+    public void setBeamPushUris(Uri[] uris, Activity activity) {
         if (activity == null) {
             throw new NullPointerException("activity cannot be null");
         }
-        mNfcActivityManager.setNdefPushContentUri(activity, mimeType, uri);
+        mNfcActivityManager.setNdefPushContentUri(activity, uris);
+    }
+
+    // TODO javadoc
+    public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity cannot be null");
+        }
+        mNfcActivityManager.setNdefPushContentUriCallback(activity, callback);
     }
 
     /**
diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java
new file mode 100644
index 0000000..8de4e06
--- /dev/null
+++ b/core/java/android/os/NullVibrator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.os;
+
+import android.util.Log;
+
+/**
+ * Vibrator implementation that does nothing.
+ *
+ * @hide
+ */
+public class NullVibrator extends Vibrator {
+    private static final NullVibrator sInstance = new NullVibrator();
+
+    private NullVibrator() {
+    }
+
+    public static NullVibrator getInstance() {
+        return sInstance;
+    }
+
+    @Override
+    public boolean hasVibrator() {
+        return false;
+    }
+
+    @Override
+    public void vibrate(long milliseconds) {
+    }
+
+    @Override
+    public void vibrate(long[] pattern, int repeat) {
+        if (repeat >= pattern.length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    @Override
+    public void cancel() {
+    }
+}
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
new file mode 100644
index 0000000..7c5a47e
--- /dev/null
+++ b/core/java/android/os/SystemVibrator.java
@@ -0,0 +1,94 @@
+/*
+ * 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.os;
+
+import android.util.Log;
+
+/**
+ * Vibrator implementation that controls the main system vibrator.
+ *
+ * @hide
+ */
+public class SystemVibrator extends Vibrator {
+    private static final String TAG = "Vibrator";
+
+    private final IVibratorService mService;
+    private final Binder mToken = new Binder();
+
+    public SystemVibrator() {
+        mService = IVibratorService.Stub.asInterface(
+                ServiceManager.getService("vibrator"));
+    }
+
+    @Override
+    public boolean hasVibrator() {
+        if (mService == null) {
+            Log.w(TAG, "Failed to vibrate; no vibrator service.");
+            return false;
+        }
+        try {
+            return mService.hasVibrator();
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    @Override
+    public void vibrate(long milliseconds) {
+        if (mService == null) {
+            Log.w(TAG, "Failed to vibrate; no vibrator service.");
+            return;
+        }
+        try {
+            mService.vibrate(milliseconds, mToken);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to vibrate.", e);
+        }
+    }
+
+    @Override
+    public void vibrate(long[] pattern, int repeat) {
+        if (mService == null) {
+            Log.w(TAG, "Failed to vibrate; no vibrator service.");
+            return;
+        }
+        // catch this here because the server will do nothing.  pattern may
+        // not be null, let that be checked, because the server will drop it
+        // anyway
+        if (repeat < pattern.length) {
+            try {
+                mService.vibratePattern(pattern, repeat, mToken);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to vibrate.", e);
+            }
+        } else {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    @Override
+    public void cancel() {
+        if (mService == null) {
+            return;
+        }
+        try {
+            mService.cancelVibrate(mToken);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to cancel vibration.", e);
+        }
+    }
+}
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 3769cfe..3f783c9 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -16,61 +16,37 @@
 
 package android.os;
 
-import android.util.Log;
+import android.content.Context;
 
 /**
  * Class that operates the vibrator on the device.
  * <p>
  * If your process exits, any vibration you started with will stop.
  * </p>
+ *
+ * To obtain an instance of the system vibrator, call
+ * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
  */
-public class Vibrator
-{
-    private static final String TAG = "Vibrator";
-
-    IVibratorService mService;
-    private final Binder mToken = new Binder();
-
-    /** @hide */
-    public Vibrator()
-    {
-        mService = IVibratorService.Stub.asInterface(
-                ServiceManager.getService("vibrator"));
+public abstract class Vibrator {
+    /**
+     * @hide to prevent subclassing from outside of the framework
+     */
+    public Vibrator() {
     }
 
     /**
-     * Check whether the hardware has a vibrator.  Returns true if a vibrator
-     * exists, else false.
+     * Check whether the hardware has a vibrator.
+     *
+     * @return True if the hardware has a vibrator, else false.
      */
-    public boolean hasVibrator() {
-        if (mService == null) {
-            Log.w(TAG, "Failed to vibrate; no vibrator service.");
-            return false;
-        }
-        try {
-            return mService.hasVibrator();
-        } catch (RemoteException e) {
-        }
-        return false;
-    }
+    public abstract boolean hasVibrator();
     
     /**
-     * Turn the vibrator on.
+     * Vibrate constantly for the specified period of time.
      *
      * @param milliseconds The number of milliseconds to vibrate.
      */
-    public void vibrate(long milliseconds)
-    {
-        if (mService == null) {
-            Log.w(TAG, "Failed to vibrate; no vibrator service.");
-            return;
-        }
-        try {
-            mService.vibrate(milliseconds, mToken);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to vibrate.", e);
-        }
-    }
+    public abstract void vibrate(long milliseconds);
 
     /**
      * Vibrate with a given pattern.
@@ -90,38 +66,10 @@
      * @param repeat the index into pattern at which to repeat, or -1 if
      *        you don't want to repeat.
      */
-    public void vibrate(long[] pattern, int repeat)
-    {
-        if (mService == null) {
-            Log.w(TAG, "Failed to vibrate; no vibrator service.");
-            return;
-        }
-        // catch this here because the server will do nothing.  pattern may
-        // not be null, let that be checked, because the server will drop it
-        // anyway
-        if (repeat < pattern.length) {
-            try {
-                mService.vibratePattern(pattern, repeat, mToken);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to vibrate.", e);
-            }
-        } else {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-    }
+    public abstract void vibrate(long[] pattern, int repeat);
 
     /**
      * Turn the vibrator off.
      */
-    public void cancel()
-    {
-        if (mService == null) {
-            return;
-        }
-        try {
-            mService.cancelVibrate(mToken);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to cancel vibration.", e);
-        }
-    }
+    public abstract void cancel();
 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index ce4e614..035d8c4 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -7504,7 +7504,7 @@
      * <p>
      * Applications can also clear all usage information with:
      * <pre>
-     * boolean successful = resolver.delete(DataUsageFeedback.FEEDBACK_URI, null, null) > 0;
+     * boolean successful = resolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0;
      * </pre>
      * </p>
      */
@@ -7518,6 +7518,14 @@
                 Uri.withAppendedPath(Data.CONTENT_URI, "usagefeedback");
 
         /**
+         * The content:// style URI for deleting all usage information.
+         * Must be used with {@link ContentResolver#delete(Uri, String, String[])}.
+         * The {@code where} and {@code selectionArgs} parameters are ignored.
+         */
+        public static final Uri DELETE_USAGE_URI =
+                Uri.withAppendedPath(Contacts.CONTENT_URI, "delete_usage");
+
+        /**
          * <p>
          * Name for query parameter specifying the type of data usage.
          * </p>
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index bd6170b..cd8d51f 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -704,6 +704,37 @@
          */
         public static final int STATUS_BLOCKED = 498;
 
+        /** {@hide} */
+        public static String statusToString(int status) {
+            switch (status) {
+                case STATUS_PENDING: return "PENDING";
+                case STATUS_RUNNING: return "RUNNING";
+                case STATUS_PAUSED_BY_APP: return "PAUSED_BY_APP";
+                case STATUS_WAITING_TO_RETRY: return "WAITING_TO_RETRY";
+                case STATUS_WAITING_FOR_NETWORK: return "WAITING_FOR_NETWORK";
+                case STATUS_QUEUED_FOR_WIFI: return "QUEUED_FOR_WIFI";
+                case STATUS_INSUFFICIENT_SPACE_ERROR: return "INSUFFICIENT_SPACE_ERROR";
+                case STATUS_DEVICE_NOT_FOUND_ERROR: return "DEVICE_NOT_FOUND_ERROR";
+                case STATUS_SUCCESS: return "SUCCESS";
+                case STATUS_BAD_REQUEST: return "BAD_REQUEST";
+                case STATUS_NOT_ACCEPTABLE: return "NOT_ACCEPTABLE";
+                case STATUS_LENGTH_REQUIRED: return "LENGTH_REQUIRED";
+                case STATUS_PRECONDITION_FAILED: return "PRECONDITION_FAILED";
+                case STATUS_FILE_ALREADY_EXISTS_ERROR: return "FILE_ALREADY_EXISTS_ERROR";
+                case STATUS_CANNOT_RESUME: return "CANNOT_RESUME";
+                case STATUS_CANCELED: return "CANCELED";
+                case STATUS_UNKNOWN_ERROR: return "UNKNOWN_ERROR";
+                case STATUS_FILE_ERROR: return "FILE_ERROR";
+                case STATUS_UNHANDLED_REDIRECT: return "UNHANDLED_REDIRECT";
+                case STATUS_UNHANDLED_HTTP_CODE: return "UNHANDLED_HTTP_CODE";
+                case STATUS_HTTP_DATA_ERROR: return "HTTP_DATA_ERROR";
+                case STATUS_HTTP_EXCEPTION: return "HTTP_EXCEPTION";
+                case STATUS_TOO_MANY_REDIRECTS: return "TOO_MANY_REDIRECTS";
+                case STATUS_BLOCKED: return "BLOCKED";
+                default: return Integer.toString(status);
+            }
+        }
+
         /**
          * This download is visible but only shows in the notifications
          * while it's in progress.
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 8c97293..35e2e4a 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -147,6 +147,15 @@
         return out.toString();
     }
 
+    /**
+     * Returns an HTML escaped representation of the given plain text.
+     */
+    public static String escapeHtml(CharSequence text) {
+        StringBuilder out = new StringBuilder();
+        withinStyle(out, text, 0, text.length());
+        return out.toString();
+    }
+
     private static void withinHtml(StringBuilder out, Spanned text) {
         int len = text.length();
 
@@ -370,7 +379,7 @@
         }
     }
 
-    private static void withinStyle(StringBuilder out, Spanned text,
+    private static void withinStyle(StringBuilder out, CharSequence text,
                                     int start, int end) {
         for (int i = start; i < end; i++) {
             char c = text.charAt(i);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 4ebb679..4848a7a 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,9 +16,12 @@
 
 package android.view;
 
+import android.content.Context;
 import android.hardware.input.InputManager;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Vibrator;
+import android.os.NullVibrator;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -46,8 +49,11 @@
     private final int mSources;
     private final int mKeyboardType;
     private final KeyCharacterMap mKeyCharacterMap;
+    private final boolean mHasVibrator;
     private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
 
+    private Vibrator mVibrator; // guarded by mMotionRanges during initialization
+
     /**
      * A mask for input source classes.
      * 
@@ -304,7 +310,7 @@
 
     // Called by native code.
     private InputDevice(int id, int generation, String name, String descriptor, int sources,
-            int keyboardType, KeyCharacterMap keyCharacterMap) {
+            int keyboardType, KeyCharacterMap keyCharacterMap, boolean hasVibrator) {
         mId = id;
         mGeneration = generation;
         mName = name;
@@ -312,6 +318,7 @@
         mSources = sources;
         mKeyboardType = keyboardType;
         mKeyCharacterMap = keyCharacterMap;
+        mHasVibrator = hasVibrator;
     }
 
     private InputDevice(Parcel in) {
@@ -322,6 +329,7 @@
         mSources = in.readInt();
         mKeyboardType = in.readInt();
         mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in);
+        mHasVibrator = in.readInt() != 0;
 
         for (;;) {
             int axis = in.readInt();
@@ -522,6 +530,31 @@
     }
 
     /**
+     * Gets the vibrator service associated with the device, if there is one.
+     * Even if the device does not have a vibrator, the result is never null.
+     * Use {@link Vibrator#hasVibrator} to determine whether a vibrator is
+     * present.
+     *
+     * Note that the vibrator associated with the device may be different from
+     * the system vibrator.  To obtain an instance of the system vibrator instead, call
+     * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
+     *
+     * @return The vibrator service associated with the device, never null.
+     */
+    public Vibrator getVibrator() {
+        synchronized (mMotionRanges) {
+            if (mVibrator == null) {
+                if (mHasVibrator) {
+                    mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId);
+                } else {
+                    mVibrator = NullVibrator.getInstance();
+                }
+            }
+            return mVibrator;
+        }
+    }
+
+    /**
      * Provides information about the range of values for a particular {@link MotionEvent} axis.
      *
      * @see InputDevice#getMotionRange(int)
@@ -617,6 +650,7 @@
         out.writeInt(mSources);
         out.writeInt(mKeyboardType);
         mKeyCharacterMap.writeToParcel(out, flags);
+        out.writeInt(mHasVibrator ? 1 : 0);
 
         final int numRanges = mMotionRanges.size();
         for (int i = 0; i < numRanges; i++) {
@@ -657,6 +691,8 @@
         }
         description.append("\n");
 
+        description.append("  Has Vibrator: ").append(mHasVibrator).append("\n");
+
         description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
         appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
         appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 9152cc3..110c239 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -263,7 +263,7 @@
                 | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
 
         mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
-        mVibrator = new Vibrator();
+        mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
 
         mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
         mShowCombinedVolumes = !mVoiceCapable && !useMasterVolume;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index cbff58c..040a385 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1681,7 +1681,7 @@
         final int itemCount = clipData.getItemCount();
         for (int i=0; i < itemCount; i++) {
             Item item = clipData.getItemAt(i);
-            content.append(item.coerceToText(mTextView.getContext()));
+            content.append(item.coerceToStyledText(mTextView.getContext()));
         }
 
         final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY());
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9867e47..3b0fb36 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7710,7 +7710,7 @@
         if (clip != null) {
             boolean didFirst = false;
             for (int i=0; i<clip.getItemCount(); i++) {
-                CharSequence paste = clip.getItemAt(i).coerceToText(getContext());
+                CharSequence paste = clip.getItemAt(i).coerceToStyledText(getContext());
                 if (paste != null) {
                     if (!didFirst) {
                         long minMax = prepareSpacesAroundPaste(min, max, paste);
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index a0e125a..37567fd 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -29,9 +29,9 @@
 import android.widget.Toast;
 
 public class PlatLogoActivity extends Activity {
+    Vibrator mZzz;
     Toast mToast;
     ImageView mContent;
-    Vibrator mZzz = new Vibrator();
     int mCount;
     final Handler mHandler = new Handler();
 
@@ -63,7 +63,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        
+
+        mZzz = (Vibrator)getSystemService(VIBRATOR_SERVICE);
         mToast = Toast.makeText(this, "Android 4.0: Ice Cream Sandwich", Toast.LENGTH_SHORT);
 
         mContent = new ImageView(this);
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 77d0c97..6a46929 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -37,6 +37,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Vibrator;
+import android.os.SystemVibrator;
 import android.os.storage.IMountService;
 import android.os.storage.IMountShutdownObserver;
 
@@ -399,7 +400,7 @@
             }
         } else if (SHUTDOWN_VIBRATE_MS > 0) {
             // vibrate before shutting down
-            Vibrator vibrator = new Vibrator();
+            Vibrator vibrator = new SystemVibrator();
             try {
                 vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
             } catch (Exception e) {
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 3973344..0c5d5ef 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -150,6 +150,24 @@
      */
     public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4;
 
+    private static final int CMD_TO_STRING_COUNT = CMD_CHANNEL_DISCONNECTED + 1;
+    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
+    static {
+        sCmdToString[CMD_CHANNEL_HALF_CONNECTED - BASE] = "CMD_CHANNEL_HALF_CONNECTED";
+        sCmdToString[CMD_CHANNEL_FULL_CONNECTION - BASE] = "CMD_CHANNEL_FULL_CONNECTION";
+        sCmdToString[CMD_CHANNEL_FULLY_CONNECTED - BASE] = "CMD_CHANNEL_FULLY_CONNECTED";
+        sCmdToString[CMD_CHANNEL_DISCONNECT - BASE] = "CMD_CHANNEL_DISCONNECT";
+        sCmdToString[CMD_CHANNEL_DISCONNECTED - BASE] = "CMD_CHANNEL_DISCONNECTED";
+    }
+    protected static String cmdToString(int cmd) {
+        cmd -= BASE;
+        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
+            return sCmdToString[cmd];
+        } else {
+            return null;
+        }
+    }
+
     /** Successful status always 0, !0 is an unsuccessful status */
     public static final int STATUS_SUCCESSFUL = 0;
 
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 07496a7..1391ac3 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -20,9 +20,13 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
+import android.text.TextUtils;
 import android.util.Log;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.HashMap;
 import java.util.Vector;
 
@@ -444,9 +448,11 @@
      * The information maintained for a processed message.
      */
     public static class ProcessedMessageInfo {
-        private int what;
-        private State state;
-        private State orgState;
+        private long mTime;
+        private int mWhat;
+        private String mInfo;
+        private State mState;
+        private State mOrgState;
 
         /**
          * Constructor
@@ -455,8 +461,8 @@
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        ProcessedMessageInfo(Message message, State state, State orgState) {
-            update(message, state, orgState);
+        ProcessedMessageInfo(Message msg, String info, State state, State orgState) {
+            update(msg, info, state, orgState);
         }
 
         /**
@@ -465,31 +471,47 @@
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        public void update(Message message, State state, State orgState) {
-            this.what = message.what;
-            this.state = state;
-            this.orgState = orgState;
+        public void update(Message msg, String info, State state, State orgState) {
+            mTime = System.currentTimeMillis();
+            mWhat = msg.what;
+            mInfo = info;
+            mState = state;
+            mOrgState = orgState;
+        }
+
+        /**
+         * @return time stamp
+         */
+        public long getTime() {
+            return mTime;
+        }
+
+        /**
+         * @return msg.what
+         */
+        public long getWhat() {
+            return mWhat;
         }
 
         /**
          * @return the command that was executing
          */
-        public int getWhat() {
-            return what;
+        public String getInfo() {
+            return mInfo;
         }
 
         /**
          * @return the state that handled this message
          */
         public State getState() {
-            return state;
+            return mState;
         }
 
         /**
          * @return the original state that received the message.
          */
         public State getOriginalState() {
-            return orgState;
+            return mOrgState;
         }
 
         /**
@@ -498,26 +520,24 @@
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
-            sb.append("what=");
-            sb.append(what);
+            sb.append("time=");
+            Calendar c = Calendar.getInstance();
+            c.setTimeInMillis(mTime);
+            sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
             sb.append(" state=");
-            sb.append(cn(state));
+            sb.append(mState == null ? "<null>" : mState.getName());
             sb.append(" orgState=");
-            sb.append(cn(orgState));
-            return sb.toString();
-        }
-
-        /**
-         * @return an objects class name
-         */
-        private String cn(Object n) {
-            if (n == null) {
-                return "null";
-            } else {
-                String name = n.getClass().getName();
-                int lastDollar = name.lastIndexOf('$');
-                return name.substring(lastDollar + 1);
+            sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
+            sb.append(" what=");
+            sb.append(mWhat);
+            sb.append("(0x");
+            sb.append(Integer.toHexString(mWhat));
+            sb.append(")");
+            if ( ! TextUtils.isEmpty(mInfo)) {
+                sb.append(" ");
+                sb.append(mInfo);
             }
+            return sb.toString();
         }
     }
 
@@ -542,9 +562,9 @@
         private int mCount = 0;
 
         /**
-         * Constructor
+         * private constructor use add
          */
-        ProcessedMessages() {
+        private ProcessedMessages() {
         }
 
         /**
@@ -599,22 +619,23 @@
         /**
          * Add a processed message.
          *
-         * @param message
+         * @param msg
+         * @param messageInfo to be stored
          * @param state that handled the message
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        void add(Message message, State state, State orgState) {
+        void add(Message msg, String messageInfo, State state, State orgState) {
             mCount += 1;
             if (mMessages.size() < mMaxSize) {
-                mMessages.add(new ProcessedMessageInfo(message, state, orgState));
+                mMessages.add(new ProcessedMessageInfo(msg, messageInfo, state, orgState));
             } else {
                 ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);
                 mOldestIndex += 1;
                 if (mOldestIndex >= mMaxSize) {
                     mOldestIndex = 0;
                 }
-                pmi.update(message, state, orgState);
+                pmi.update(msg, messageInfo, state, orgState);
             }
         }
     }
@@ -894,11 +915,14 @@
             /**
              * Record that we processed the message
              */
-            if (curStateInfo != null) {
-                State orgState = mStateStack[mStateStackTopIndex].state;
-                mProcessedMessages.add(msg, curStateInfo.state, orgState);
-            } else {
-                mProcessedMessages.add(msg, null, null);
+            if (mSm.recordProcessedMessage(msg)) {
+                if (curStateInfo != null) {
+                    State orgState = mStateStack[mStateStackTopIndex].state;
+                    mProcessedMessages.add(msg, mSm.getMessageInfo(msg), curStateInfo.state,
+                            orgState);
+                } else {
+                    mProcessedMessages.add(msg, mSm.getMessageInfo(msg), null, null);
+                }
             }
         }
 
@@ -1546,6 +1570,24 @@
     }
 
     /**
+     * @return true if msg should be saved in ProcessedMessage, default is true.
+     */
+    protected boolean recordProcessedMessage(Message msg) {
+        return true;
+    }
+
+    /**
+     * Return message info to be logged by ProcessedMessageInfo, default
+     * is an empty string. Override if additional information is desired.
+     *
+     * @param msg that was processed
+     * @return information to be logged as a String
+     */
+    protected String getMessageInfo(Message msg) {
+        return "";
+    }
+
+    /**
      * @return if debugging is enabled
      */
     public boolean isDbg() {
@@ -1577,4 +1619,21 @@
         /** Send the complete construction message */
         mSmHandler.completeConstruction();
     }
+
+    /**
+     * Dump the current state.
+     *
+     * @param fd
+     * @param pw
+     * @param args
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println(getName() + ":");
+        pw.println(" total messages=" + getProcessedMessagesCount());
+        for (int i=0; i < getProcessedMessagesSize(); i++) {
+            pw.printf(" msg[%d]: %s\n", i, getProcessedMessageInfo(i));
+            pw.flush();
+        }
+        pw.println("curState=" + getCurrentState().getName());
+    }
 }
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index e8a3a3b..5cb172b 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -57,7 +57,7 @@
             gInputDeviceClassInfo.ctor, deviceInfo.getId(), deviceInfo.getGeneration(),
             nameObj.get(), descriptorObj.get(),
             deviceInfo.getSources(), deviceInfo.getKeyboardType(),
-            kcmObj.get()));
+            kcmObj.get(), deviceInfo.hasVibrator()));
 
     const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
     for (size_t i = 0; i < ranges.size(); i++) {
@@ -87,7 +87,7 @@
     gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
 
     GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
-            "<init>", "(IILjava/lang/String;Ljava/lang/String;IILandroid/view/KeyCharacterMap;)V");
+            "<init>", "(IILjava/lang/String;Ljava/lang/String;IILandroid/view/KeyCharacterMap;Z)V");
 
     GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
             "addMotionRange", "(IIFFFF)V");
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
index 6b06456..78b7d29 100644
--- a/core/res/res/anim/lock_screen_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -20,8 +20,8 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:background="#ff000000" android:shareInterpolator="false">
     <scale
-        android:fromXScale="0.95" android:toXScale="1.0"
-        android:fromYScale="0.95" android:toYScale="1.0"
+        android:fromXScale="0.90" android:toXScale="1.0"
+        android:fromYScale="0.90" android:toYScale="1.0"
         android:pivotX="50%p" android:pivotY="50%p"
         android:fillEnabled="true" android:fillBefore="true"
         android:interpolator="@interpolator/decelerate_cubic"
@@ -30,7 +30,7 @@
     <alpha
         android:fromAlpha="0.0" android:toAlpha="1.0"
         android:fillEnabled="true" android:fillBefore="true"
-        android:interpolator="@interpolator/decelerate_quad"
+        android:interpolator="@interpolator/decelerate_quint"
         android:startOffset="@android:integer/config_shortAnimTime"
         android:duration="@android:integer/config_shortAnimTime"/>
 </set>
\ No newline at end of file
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9528a7a..25fc3a0 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Laat die program toe om die skerm se rotasie te eniger tyd te verander. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"verander wyserspoed"</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Laat die program toe om die muis of stuurpaneel se wyserspoed te eniger tyd te verander. Dit moet nooit vir normale programme nodig wees nie."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"verander sleutelborduitleg"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Laat die program toe om die uitleg van die sleutelbord te verander. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"stuur Linux-seine na programme"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Laat die program toe om te versoek dat die voorsiende sein na alle aanhoudende prosesse gestuur word."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"laat program altyd loop"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak om USB-ontfouting te deaktiveer."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Kies invoermetode"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Stel invoermetodes op"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Fisiese sleutelbord"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardeware"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidate"</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Verminder dag"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Vermeerder jaar"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Verminder jaar"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"gekontroleer"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nie gekontroleer nie"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"gekies"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nie gekies nie"</string>
-    <string name="switch_on" msgid="551417728476977311">"aan"</string>
-    <string name="switch_off" msgid="7249798614327155088">"af"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"gedruk"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nie gedruk nie"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Kanselleer"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Vee uit"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 747b12d..0764f0e 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"ቀን ቀንስ"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"ዓመት ጨምር"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"ዓመት ቀንስ"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"ታይቷል"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"አልተፈተሸም"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"የተመረጠ"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"አልተመረጠም"</string>
-    <string name="switch_on" msgid="551417728476977311">"በ:"</string>
-    <string name="switch_off" msgid="7249798614327155088">"ውጪ"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"ተጭኗል"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"አልተጫነም።"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ተወው"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ሰርዝ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index e95ea69..cc3cf93 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"تقليل الأيام"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"زيادة الأعوام"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"تقليل الأعوام"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"تم التحديد"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"لم يتم التحديد"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"محدد"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"غير محدد"</string>
-    <string name="switch_on" msgid="551417728476977311">"تشغيل"</string>
-    <string name="switch_off" msgid="7249798614327155088">"إيقاف"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"مضغوط"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"غير مضغوط"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"إلغاء"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"حذف"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c78ecd9..16cb445 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дазваляе прыкладанням змяняць паварот экрана ў любы час. Не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змена хутк. перамяшч. ўказ."</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дазваляе прыкладанням змяняць хуткасць курсору мышы або трэкпада ў любы час. Не патрабуецца для звычайных прыкладанняў."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"змяніць раскладку клавіятуры"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Дазваляе прыкладанню змяняць раскладку клавіятуры. Не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"адправіць сігналы Linux да прыкладанняў"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дазваляе прыкладанням запытваць адпраўку падаваемага сігнала для ўсiх пастаянных працэсаў."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"прымусіць прыкладанне працаваць заўсёды"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Націсніце, каб адключыць адладку USB."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Выберыце метад уводу"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Наладзіць метады ўводу"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Фізічная клавіятура"</string>
+    <string name="hardware" msgid="7517821086888990278">"Апар. ср."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Паменшыць лічбу дня"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Павялічыць лічбу года"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Паменшыць лічбу года"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"пастаўлены"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"не пастаўлены"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"абрана"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"не абрана"</string>
-    <string name="switch_on" msgid="551417728476977311">"укл."</string>
-    <string name="switch_off" msgid="7249798614327155088">"адключаны"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"націснутая"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"не націснутая"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Адмена"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Выдаліць"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 8bcbec3..83f5e41 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Намаляване на дните"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Увеличаване на годините"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Намаляване на годините"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"отметнато"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"не е отметнато"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"избрано"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"не е избрано"</string>
-    <string name="switch_on" msgid="551417728476977311">"включено"</string>
-    <string name="switch_off" msgid="7249798614327155088">"изключено"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"натиснато"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"не е натиснато"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Отказ"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Изтриване"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index fdae718..c72c2dd 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Fes disminuir el dia"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Fes augmentar l\'any"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Fes disminuir l\'any"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"marcat"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"no marcat"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionat"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"no seleccionat"</string>
-    <string name="switch_on" msgid="551417728476977311">"activat"</string>
-    <string name="switch_off" msgid="7249798614327155088">"desactivat"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"premut"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"no premut"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel·la"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Suprimeix"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 98b5771..52d10a2 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Ubrat den"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Přidat rok"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Ubrat rok"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"zaškrtnuto"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nezaškrtnuto"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"Vybráno"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"Nevybráno"</string>
-    <string name="switch_on" msgid="551417728476977311">"zapnuto"</string>
-    <string name="switch_off" msgid="7249798614327155088">"vypnuto"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"stisknuto"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nestisknuto"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušit"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Smazat"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index a3c7474..b0a487b 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Tillader, at appen kan ændre skærmretningen på et hvilket som helst tidspunkt. Bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ændre markørens hastighed"</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Tillader, at appen til enhver tid kan ændre musemarkørens hastighed. Bør aldrig være nødvendigt for normale apps."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"skift tastaturlayout"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Tillader, at appen må ændre tastaturlayoutet. Bør aldrig være nødvendig for normale apps."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"sende Linux-signaler til apps"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Tillader, at appen kan anmode om, at det leverede signal sendes til alle vedholdende processer."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"sørge for, at appen altid kører"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryk for at deaktivere USB-fejlretning."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Vælg inputmetode"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inputmetoder"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Tidligere dag"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Senere år"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Tidligere år"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"markeret"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"ikke markeret"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"udvalgt"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"ikke valgt"</string>
-    <string name="switch_on" msgid="551417728476977311">"tændt"</string>
-    <string name="switch_off" msgid="7249798614327155088">"slukket"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"trykket på"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"ikke trykket på"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuller"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Slet"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ae889201..27b88f4 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Tag verringern"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Jahr verlängern"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Jahr verringern"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"Aktiviert"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"Nicht aktiviert"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"Ausgewählt"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"Nicht ausgewählt"</string>
-    <string name="switch_on" msgid="551417728476977311">"An"</string>
-    <string name="switch_off" msgid="7249798614327155088">"Aus"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"Gedrückt"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"Nicht gedrückt"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Abbrechen"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Löschen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ce49a84..0a5dd69 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Μείωση ημέρας"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Αύξηση έτους"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Μείωση έτους"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"ελέγχθηκε"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"δεν επιλέχθηκε"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"επιλεγμένο"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"δεν έχει επιλεγεί"</string>
-    <string name="switch_on" msgid="551417728476977311">"ενεργοποίηση"</string>
-    <string name="switch_off" msgid="7249798614327155088">"απενεργοποιημένη"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"πατήθηκε"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"δεν πατήθηκε"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ακύρωση"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Διαγραφή"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 38b69fe..fe5a173 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Allows the app to change the rotation of the screen at any time. Should never be needed for normal apps."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"change pointer speed"</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Allows the app to change the mouse or touch pad pointer speed at any time. Should never be needed for normal apps."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"change keyboard layout"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Allows the app to change the keyboard layout. Should never be needed for normal apps."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"send Linux signals to apps"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Allows the app to request that the supplied signal be sent to all persistent processes."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"make app always run"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Choose input method"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Set up input methods"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Physical keyboard"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Decrease day"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Increase year"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Decrease year"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"ticked"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"not ticked"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"selected"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"not selected"</string>
-    <string name="switch_on" msgid="551417728476977311">"on"</string>
-    <string name="switch_off" msgid="7249798614327155088">"off"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"pressed"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"not pressed"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index d400734..ade6cfb 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reducir día"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar año"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reducir año"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"marcado"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"no marcado"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"No se ha seleccionado."</string>
-    <string name="switch_on" msgid="551417728476977311">"Activado"</string>
-    <string name="switch_off" msgid="7249798614327155088">"Desactivado"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"presionado"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"sin presionar"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Eliminar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 6852184..8f50660 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reducir días"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar año"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reducir año"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"seleccionado"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"no seleccionado"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"no seleccionado"</string>
-    <string name="switch_on" msgid="551417728476977311">"activado"</string>
-    <string name="switch_off" msgid="7249798614327155088">"desactivado"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"pulsado"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"sin pulsar"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Eliminar"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 737ab21..25f3752 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Võimaldab rakendusel muuta ekraani pööramist mis tahes ajal. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"kursorikiiruse muutmine"</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Võimaldab rakendusel muuta igal ajal hiire- või puutepadjakursori kiirust. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"klaviatuuri paigutuse muutmine"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Lubab rakendusel muuta klaviatuuri paigutust. Tavarakenduste puhul ei peaks kunagi vaja olema."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linuxi signaalide saatmine rakendustele"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Võimaldab rakendusel taotleda edastatud signaali saatmist kõigile püsiprotsessidele."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"Rakenduste pidev töös hoidmine"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Valige sisestusmeetod"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Seadista sisestusmeetodid"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Füüsiline klaviatuur"</string>
+    <string name="hardware" msgid="7517821086888990278">"Riistvara"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaadid"</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Päeva vähendamine"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aasta suurendamine"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Aasta vähendamine"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"märgitud"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"pole märgitud"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"valitud"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"pole valitud"</string>
-    <string name="switch_on" msgid="551417728476977311">"sees"</string>
-    <string name="switch_off" msgid="7249798614327155088">"väljas"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"vajutatud"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"pole vajutatud"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Tühista"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Kustuta"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 80b273b..d60c59d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"کاهش روز"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"افزایش سال"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"کاهش سال"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"علامت زده"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"بدون علامت"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"انتخاب شد"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"انتخاب نشده"</string>
-    <string name="switch_on" msgid="551417728476977311">"روشن"</string>
-    <string name="switch_off" msgid="7249798614327155088">"خاموش"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"فشرده شد"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"فشرده نشد"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"لغو"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f011ec3..211fab2 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Vähennä päivien määrää."</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Lisää vuosien määrää."</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Vähennä vuosien määrää."</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"valittu"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"ei valittu"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"valittu"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"ei valittu"</string>
-    <string name="switch_on" msgid="551417728476977311">"käytössä"</string>
-    <string name="switch_off" msgid="7249798614327155088">"pois käytöstä"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"painettu"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"ei painettu"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Peruuta"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Poista"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7c78654..787bdda 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permet à l\'application de changer l\'orientation de l\'écran à tout moment. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"changer la vitesse du pointeur"</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permet à l\'application de modifier à tout moment la vitesse du pointeur de la souris ou du pavé tactile. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"changer disposition clavier"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Permet à l\'application de changer la disposition du clavier. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"envoyer des signaux Linux aux applications"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permet à l\'application de demander que le signal fourni soit envoyé à tous les processus persistants."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"exécuter l\'application en continu"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Sélectionnez le mode de saisie"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
+    <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Jour précédent"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Année suivante"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Année précédente"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"coché"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"non coché"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"sélectionné"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"non sélectionné"</string>
-    <string name="switch_on" msgid="551417728476977311">"activé"</string>
-    <string name="switch_off" msgid="7249798614327155088">"désactivé"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"sélectionné"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"non sélectionné"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuler"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Supprimer"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 1ee3d03..1a95f32 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"दिन कम करें"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"वर्ष बढ़ाएं"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"वर्ष कम करें"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"चेक किया गया"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"चेक नहीं किया गया"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"चयनित"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"चयनित नहीं"</string>
-    <string name="switch_on" msgid="551417728476977311">"चालू"</string>
-    <string name="switch_off" msgid="7249798614327155088">"बंद"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"दबाया गया"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"दबाया नहीं गया."</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द करें"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"हटाएं"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0023310..0591e04 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Smanjenje dana"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Povećanje godine"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Smanjenje godine"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"označeno"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nije označeno"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"odabran"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nije odabrano"</string>
-    <string name="switch_on" msgid="551417728476977311">"uključeno"</string>
-    <string name="switch_off" msgid="7249798614327155088">"isključeno"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"pritisnut"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nije pritisnut"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Odustani"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Izbriši"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4ae52d5..4043aef 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Dátum értékének csökkentése"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Év értékének növelése"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Év értékének csökkentése"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"bejelölve"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nincs bejelölve"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"bejelölve"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nincs kiválasztva"</string>
-    <string name="switch_on" msgid="551417728476977311">"be"</string>
-    <string name="switch_off" msgid="7249798614327155088">"kikapcsolva"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"megnyomva"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nincs megnyomva"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Mégse"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index bd6294b..7a52979 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -109,7 +109,7 @@
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Tidak diteruskan"</string>
     <string name="fcComplete" msgid="3118848230966886575">"Kode fitur selesai."</string>
     <string name="fcError" msgid="3327560126588500777">"Masalah sambungan atau kode fitur tidak valid."</string>
-    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"Oke"</string>
     <string name="httpError" msgid="7956392511146698522">"Terjadi kesalahan jaringan."</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"Tidak dapat menemukan URL."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Skema autentikasi situs tidak didukung."</string>
@@ -744,7 +744,7 @@
     <string name="factorytest_reboot" msgid="6320168203050791643">"Mulai ulang"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"Laman pada \"<xliff:g id="TITLE">%s</xliff:g>\" menyatakan:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
-    <string name="js_dialog_before_unload" msgid="730366588032430474">"Beranjak dari laman ini?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sentuh OK untuk melanjutkan atau Batal untuk tetap pada laman ini."</string>
+    <string name="js_dialog_before_unload" msgid="730366588032430474">"Beranjak dari laman ini?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sentuh Oke untuk melanjutkan atau Batal untuk tetap pada laman ini."</string>
     <string name="save_password_label" msgid="6860261758665825069">"Konfirmasi"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Isiotomatis"</string>
@@ -892,7 +892,7 @@
     <string name="VideoView_error_title" msgid="3534509135438353077">"Masalah video"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Video ini tidak valid untuk pengaliran ke perangkat ini."</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Tidak dapat memutar video ini."</string>
-    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"Oke"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"tengah hari"</string>
     <string name="Noon" msgid="3342127745230013127">"Tengah hari"</string>
@@ -916,9 +916,9 @@
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Ruang penyimpanan tinggal sedikit"</string>
     <string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"Ruang penyimpanan tablet semakin sedikit."</string>
     <string name="low_internal_storage_view_text" product="default" msgid="635106544616378836">"Ruang penyimpanan ponsel tersisa sedikit."</string>
-    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="ok" msgid="5970060430562524910">"Oke"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
-    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="yes" msgid="5362982303337969312">"Oke"</string>
     <string name="no" msgid="5141531044935541497">"Batal"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Perhatian"</string>
     <string name="loading" msgid="7933681260296021180">"Memuat..."</string>
@@ -938,7 +938,7 @@
     <string name="anr_activity_process" msgid="5776209883299089767">"Aktivitas <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak menanggapi."\n\n"Anda ingin menutupnya?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tidak menanggapi. Anda ingin menutupnya?"</string>
     <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak menanggapi."\n\n"Anda ingin menutupnya?"</string>
-    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="force_close" msgid="8346072094521265605">"Oke"</string>
     <string name="report" msgid="4060218260984795706">"Laporkan"</string>
     <string name="wait" msgid="7147118217226317732">"Tunggu"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak menanggapi."\n\n"Apakah Anda ingin menutupnya?"</string>
@@ -1011,8 +1011,8 @@
     <string name="select_character" msgid="3365550120617701745">"Sisipkan huruf"</string>
     <string name="sms_control_default_app_name" msgid="3058577482636640465">"Apl tak dikenal"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Mengirim pesan SMS"</string>
-    <string name="sms_control_message" msgid="4073755190243093924">"Pesan SMS dalam jumlah besar sedang dikirimkan. Sentuh OK untuk melanjutkan, atau Batal untuk menghentikan pengiriman."</string>
-    <string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
+    <string name="sms_control_message" msgid="4073755190243093924">"Pesan SMS dalam jumlah besar sedang dikirimkan. Sentuh Oke untuk melanjutkan, atau Batal untuk menghentikan pengiriman."</string>
+    <string name="sms_control_yes" msgid="2532062172402615953">"Oke"</string>
     <string name="sms_control_no" msgid="1715320703137199869">"Batal"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"Kartu SIM dihapus"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"Jaringan seluler tidak akan tersedia sampai Anda memulai lagi dengan memasukkan kartu SIM yang valid."</string>
@@ -1048,7 +1048,7 @@
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Hidupkan penyimpanan USB"</string>
     <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jika Anda menyalakan penyimpanan USB, beberapa apl yang Anda gunakan akan berhenti dan mungkin tidak dapat dibuka hingga penyimpanan USB dimatikan."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB gagal"</string>
-    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Oke"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tersambung sebagai perangkat media"</string>
     <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tersambung sebagai kamera"</string>
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tersambung sebagai pemasang"</string>
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Kurangi hari"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Tambah tahun"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Kurangi tahun"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"dicentang"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"tidak diperiksa"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"tidak dipilih"</string>
-    <string name="switch_on" msgid="551417728476977311">"nyala"</string>
-    <string name="switch_off" msgid="7249798614327155088">"mati"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"ditekan"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"tidak ditekan"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Hapus"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ae52c62..9073bf1 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -286,10 +286,8 @@
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Consente all\'applicazione di cambiare la rotazione dello schermo in qualsiasi momento. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambio velocità del puntatore"</string>
     <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Consente all\'applicazione di modificare la velocità del puntatore del mouse o del trackpad in qualsiasi momento. Non dovrebbe mai essere necessaria per le applicazioni normali."</string>
-    <!-- no translation found for permlab_setKeyboardLayout (4778731703600909340) -->
-    <skip />
-    <!-- no translation found for permdesc_setKeyboardLayout (8480016771134175879) -->
-    <skip />
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"modifica del layout tastiera"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Consente all\'applicazione di modificare il layout della tastiera. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"invio segnali Linux alle applicazioni"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Consente all\'applicazione di richiedere l\'invio del segnale fornito a tutti i processi persistenti."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"esecuzione permanente delle applicazioni"</string>
@@ -1063,10 +1061,8 @@
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocca per disattivare il debug USB."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Scegli il metodo di immissione"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Configura metodi di immissione"</string>
-    <!-- no translation found for use_physical_keyboard (6203112478095117625) -->
-    <skip />
-    <!-- no translation found for hardware (7517821086888990278) -->
-    <skip />
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Tastiera fisica"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string>
@@ -1193,14 +1189,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Riduci giorno"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumenta anno"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Riduci anno"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"selezionata"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"non selezionato"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"selezionato"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"non selezionato"</string>
-    <string name="switch_on" msgid="551417728476977311">"attivo"</string>
-    <string name="switch_off" msgid="7249798614327155088">"disattivo"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"premuto"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"non premuto"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annulla"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Canc"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 613410f..714f203 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"הפחת יום"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"הוסף שנה"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"הפחת שנה"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"מסומן"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"לא מסומן"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"נבחר"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"לא נבחר"</string>
-    <string name="switch_on" msgid="551417728476977311">"מופעל"</string>
-    <string name="switch_off" msgid="7249798614327155088">"כבוי"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"לחוץ"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"לא לחוץ"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ביטול"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"מחק"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 5e5010d..a5db38b 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"1日戻します"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"1年進めます"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"1年戻します"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"ON"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"OFF"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"ON"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"選択されていません"</string>
-    <string name="switch_on" msgid="551417728476977311">"ON"</string>
-    <string name="switch_off" msgid="7249798614327155088">"OFF"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"ON"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"OFF"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"キャンセル"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"削除"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 5556aae..4f580ba 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"\'일\'을 줄입니다."</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"\'연도\'를 늘립니다."</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"\'연도\'를 줄입니다."</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"확인"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"선택 안함"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"선택됨"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"선택 안함"</string>
-    <string name="switch_on" msgid="551417728476977311">"켜짐"</string>
-    <string name="switch_off" msgid="7249798614327155088">"꺼짐"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"누름"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"누르지 않음"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt 키"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"취소"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete 키"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 9e82e8c..c588fa6 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Sumažinti dienų skaičių"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Padidinti metų skaičių"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Sumažinti metų skaičių"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"pažymėtas"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nepatikrinta"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"pasirinkta"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nepasirinkta"</string>
-    <string name="switch_on" msgid="551417728476977311">"įjungta"</string>
-    <string name="switch_off" msgid="7249798614327155088">"išjungta"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"paspausta"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nepaspausta"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Atšaukti"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ištrinti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index ae451e0..d710347 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Norādīt agrāku dienu"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Norādīt vēlāku gadu"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Norādīt agrāku gadu"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"atzīmēta"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nav atzīmēta"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"atlasīta"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nav atlasīta"</string>
-    <string name="switch_on" msgid="551417728476977311">"ieslēgts"</string>
-    <string name="switch_off" msgid="7249798614327155088">"izslēgts"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"nospiesta"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nav nospiesta"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alternēšanas taustiņš"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Atcelt"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Dzēšanas taustiņš"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index ead175b..38fc473 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Kurangkan hari"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Tingkatkan tahun"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Kurangkan tahun"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"ditandakan"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"tidak ditandakan"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"tidak dipilih"</string>
-    <string name="switch_on" msgid="551417728476977311">"hidup"</string>
-    <string name="switch_off" msgid="7249798614327155088">"mati"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"ditekan."</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"tidak ditekan"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Padam"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index bbd846f..df05f01 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reduser dager"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Øk år"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reduser år"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"valgt"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"ikke valgt"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"valgt"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"ikke valgt"</string>
-    <string name="switch_on" msgid="551417728476977311">"på"</string>
-    <string name="switch_off" msgid="7249798614327155088">"av"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"trykket"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"ikke trykket"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Avbryt"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Slett"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8440d62..3d48936 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Lagere waarde voor dag"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Hogere waarde voor jaar"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Lagere waarde voor jaar"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"aangevinkt"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"niet aangevinkt"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"geselecteerd"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"niet geselecteerd"</string>
-    <string name="switch_on" msgid="551417728476977311">"aan"</string>
-    <string name="switch_off" msgid="7249798614327155088">"uit"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"ingedrukt"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"niet ingedrukt"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuleren"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index ee1e6a3..d566c14 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Zmień dzień na wcześniejszy"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Zmień rok na późniejszy"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Zmień rok na wcześniejszy"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"zaznaczono"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nie zaznaczono"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"wybrano"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nie wybrano"</string>
-    <string name="switch_on" msgid="551417728476977311">"włączono"</string>
-    <string name="switch_off" msgid="7249798614327155088">"wyłączono"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"naciśnięto"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nie naciśnięto"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anuluj"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 393ba17..0f55711 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Diminuir dia"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar ano"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Diminuir ano"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"marcado"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"desmarcado"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"não selecionado"</string>
-    <string name="switch_on" msgid="551417728476977311">"ativado"</string>
-    <string name="switch_off" msgid="7249798614327155088">"desativado"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"premido"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"não premido"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index bb145f7..1beb4e7 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Diminuir dia"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar ano"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Diminuir ano"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"verificado"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"não selecionado"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"Não selecionado"</string>
-    <string name="switch_on" msgid="551417728476977311">"ativado"</string>
-    <string name="switch_off" msgid="7249798614327155088">"desativado"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"pressionado"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"não pressionado"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Excluir"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 8b0718f..637e4b1 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1788,22 +1788,6 @@
     <skip />
     <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
     <skip />
-    <!-- no translation found for checkbox_checked (7222044992652711167) -->
-    <skip />
-    <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
-    <skip />
-    <!-- no translation found for radiobutton_selected (8603599808486581511) -->
-    <skip />
-    <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
-    <skip />
-    <!-- no translation found for switch_on (551417728476977311) -->
-    <skip />
-    <!-- no translation found for switch_off (7249798614327155088) -->
-    <skip />
-    <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
-    <skip />
-    <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
-    <skip />
     <!-- no translation found for keyboardview_keycode_alt (4856868820040051939) -->
     <skip />
     <!-- no translation found for keyboardview_keycode_cancel (1203984017245783244) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d93d8d1..0f773a5 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reduceţi valoarea pentru zi"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Creşteţi valoarea pentru an"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reduceţi valoarea pentru an"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"bifată"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nebifată"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"selectat"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"neselectat"</string>
-    <string name="switch_on" msgid="551417728476977311">"activat"</string>
-    <string name="switch_off" msgid="7249798614327155088">"dezactivat"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"apăsat"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"neapăsat"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anulaţi"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ştergeţi"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 2743763..7b7c95bd 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"На день назад"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"На год вперед"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"На год назад"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"установлено"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"не установлено"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"выбрано"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"не выбрано"</string>
-    <string name="switch_on" msgid="551417728476977311">"Включено"</string>
-    <string name="switch_off" msgid="7249798614327155088">"Выкл."</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"нажато"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"не нажато"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Клавиша ALT"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Отмена"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Клавиша удаления"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 49d04c3..a2ac96e 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Ubrať deň"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Pridať rok"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Ubrať rok"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"začiarknuté"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"nezačiarknuté"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"vybratý"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"nie je vybraté"</string>
-    <string name="switch_on" msgid="551417728476977311">"zapnuté"</string>
-    <string name="switch_off" msgid="7249798614327155088">"vypnuté"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"stlačené"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"nestlačené"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušiť"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Odstrániť"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 55f3593..2b452ae 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Zmanjšanje vrednosti za dan"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Povečanje vrednosti za leto"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Zmanjšanje vrednosti za leto"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"potrjeno"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"ni odkljukano"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"izbrano"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"ni izbrano"</string>
-    <string name="switch_on" msgid="551417728476977311">"vklopljeno"</string>
-    <string name="switch_off" msgid="7249798614327155088">"izklopljeno"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"vklopljen"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"izklopljen"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Tipka Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Prekliči"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Tipka Delete"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index de03bec..0fdce67 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Смањивање дана"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Повећавање године"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Смањивање године"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"изабрано"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"није потврђено"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"изабрано"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"није изабрано"</string>
-    <string name="switch_on" msgid="551417728476977311">"укључено"</string>
-    <string name="switch_off" msgid="7249798614327155088">"искључено"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"притиснуто"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"није притиснуто"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Откажи"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Избриши"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 7448ff8..2c4efc5 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Minska dagar"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Öka år"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Minska år"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"markerat"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"inte markerat"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"markerade"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"ej vald"</string>
-    <string name="switch_on" msgid="551417728476977311">"på"</string>
-    <string name="switch_off" msgid="7249798614327155088">"av"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"intryckt"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"inte intryckt"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Avbryt"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ab6c82f..41345bd 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Punguza siku"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Ongeza mwaka"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Punguza mwaka"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"imeangaliwa"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"haijakaguliwa"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"Iliyochaguliwa"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"Haijachaguliwa"</string>
-    <string name="switch_on" msgid="551417728476977311">"Washa"</string>
-    <string name="switch_off" msgid="7249798614327155088">"zima"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"iliyobonyezwa"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"Haijabonyezwa"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ghairi"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Futa"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 7007522..3f479e5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"ลดวัน"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"เพิ่มปี"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"ลดปี"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"เลือกไว้"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"ไม่ได้ตรวจสอบ"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"เลือกแล้ว"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"ไม่ได้เลือก"</string>
-    <string name="switch_on" msgid="551417728476977311">"เปิด"</string>
-    <string name="switch_off" msgid="7249798614327155088">"ปิด"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"กดแล้ว"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"ไม่ได้กด"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ยกเลิก"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ลบ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 31ad6c8..a5d3f08 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Bawasan ang araw"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Dagdagdan ang taon"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Bawasan ang taon"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"nilagyan ng check"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"hindi nilagyan ng check"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"pinili"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"Hindi pinili"</string>
-    <string name="switch_on" msgid="551417728476977311">"naka-on"</string>
-    <string name="switch_off" msgid="7249798614327155088">"naka-off"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"pinindot"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"hindi pinindot"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Kanselahin"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Tanggalin"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 959d8bd..86c1a709 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Günü azalt"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Yılı artır"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Yılı azalt"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"işaretli"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"işaretlenmedi"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"seçili"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"seçili değil"</string>
-    <string name="switch_on" msgid="551417728476977311">"açık"</string>
-    <string name="switch_off" msgid="7249798614327155088">"kapalı"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"basıldı"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"basılmadı"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"İptal"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index f9d372e..154468c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"На день назад"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"На рік уперед"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"На рік назад"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"перевірено"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"не перевірено"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"вибрано"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"не вибрано"</string>
-    <string name="switch_on" msgid="551417728476977311">"увімк."</string>
-    <string name="switch_off" msgid="7249798614327155088">"вимкн."</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"натиснуто"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"не натиснуто"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Скасувати"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index dde1ad4..cbad241 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Giảm ngày"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Tăng năm"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Giảm năm"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"đã kiểm tra"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"chưa chọn"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"đã chọn"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"chưa được chọn"</string>
-    <string name="switch_on" msgid="551417728476977311">"bật"</string>
-    <string name="switch_off" msgid="7249798614327155088">"tắt"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"đã bấm"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"chưa được bấm"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Hủy"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Xóa"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 0c338bb..cb612e1 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"减小日期值"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"增大年份值"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"减小年份值"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"已选中"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"未选中"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"已选择"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"未选择"</string>
-    <string name="switch_on" msgid="551417728476977311">"已打开"</string>
-    <string name="switch_off" msgid="7249798614327155088">"已关闭"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"已按下"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"未按下"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"取消"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c36b1b5..c2ae68e 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"減少日數"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"增加年數"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"減少年數"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"已勾選"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"尚未勾選"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"已選取"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"未選取"</string>
-    <string name="switch_on" msgid="551417728476977311">"開啟"</string>
-    <string name="switch_off" msgid="7249798614327155088">"關閉"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"已按下"</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"未按下"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt 鍵"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"取消"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete 鍵"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 3b3b1e1..eea53ec 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1193,14 +1193,6 @@
     <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Yehlisa usuku"</string>
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Khulisa unyaka"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Yehlisa unyaka"</string>
-    <string name="checkbox_checked" msgid="7222044992652711167">"kuhloliwe"</string>
-    <string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string>
-    <string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string>
-    <string name="radiobutton_not_selected" msgid="2908760184307722393">"akukhethiwe"</string>
-    <string name="switch_on" msgid="551417728476977311">"vuliwe"</string>
-    <string name="switch_off" msgid="7249798614327155088">"valiwe"</string>
-    <string name="togglebutton_pressed" msgid="4180411746647422233">"kucindezelwe."</string>
-    <string name="togglebutton_not_pressed" msgid="4495147725636134425">"akucindezelwe."</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"i-ALT"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Khansela"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Susa"</string>
diff --git a/data/sounds/AllAudio.mk b/data/sounds/AllAudio.mk
index 2e18a10..e403205 100644
--- a/data/sounds/AllAudio.mk
+++ b/data/sounds/AllAudio.mk
@@ -20,3 +20,5 @@
 $(call inherit-product, frameworks/base/data/sounds/AudioPackage4.mk)
 $(call inherit-product, frameworks/base/data/sounds/AudioPackage5.mk)
 $(call inherit-product, frameworks/base/data/sounds/AudioPackage6.mk)
+$(call inherit-product, frameworks/base/data/sounds/AudioPackage7.mk)
+$(call inherit-product, frameworks/base/data/sounds/AudioPackage7alt.mk)
diff --git a/docs/html/images/training/backward-compatible-ui-classes-eclair.png b/docs/html/images/training/backward-compatible-ui-classes-eclair.png
new file mode 100644
index 0000000..febba5b
--- /dev/null
+++ b/docs/html/images/training/backward-compatible-ui-classes-eclair.png
Binary files differ
diff --git a/docs/html/images/training/backward-compatible-ui-classes-honeycomb.png b/docs/html/images/training/backward-compatible-ui-classes-honeycomb.png
new file mode 100644
index 0000000..ba14252
--- /dev/null
+++ b/docs/html/images/training/backward-compatible-ui-classes-honeycomb.png
Binary files differ
diff --git a/docs/html/images/training/backward-compatible-ui-classes.png b/docs/html/images/training/backward-compatible-ui-classes.png
new file mode 100644
index 0000000..c5a3cd8
--- /dev/null
+++ b/docs/html/images/training/backward-compatible-ui-classes.png
Binary files differ
diff --git a/docs/html/images/training/backward-compatible-ui-gb.png b/docs/html/images/training/backward-compatible-ui-gb.png
new file mode 100644
index 0000000..621ee63
--- /dev/null
+++ b/docs/html/images/training/backward-compatible-ui-gb.png
Binary files differ
diff --git a/docs/html/images/training/backward-compatible-ui-ics.png b/docs/html/images/training/backward-compatible-ui-ics.png
new file mode 100644
index 0000000..6460554
--- /dev/null
+++ b/docs/html/images/training/backward-compatible-ui-ics.png
Binary files differ
diff --git a/docs/html/images/training/implementing-navigation-up.png b/docs/html/images/training/implementing-navigation-up.png
new file mode 100644
index 0000000..18f3779
--- /dev/null
+++ b/docs/html/images/training/implementing-navigation-up.png
Binary files differ
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 5297c23..686bde3 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -227,7 +227,31 @@
           </li>
         </ul>
       </li>
-      
+
+      <li class="toggle-list">
+        <div><a href="<?cs var:toroot ?>training/backward-compatible-ui/index.html">
+            <span class="en">Creating Backward-Compatible UIs<span class="new">&nbsp;new!</span></span>
+          </a></div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/abstracting.html">
+            <span class="en">Abstracting the New APIs</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/new-implementation.html">
+            <span class="en">Proxying to the New APIs</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/older-implementation.html">
+            <span class="en">Creating an Implementation with Older APIs</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/backward-compatible-ui/using-component.html">
+            <span class="en">Using the Version-Aware Component</span>
+          </a>
+          </li>
+        </ul>
+      </li>
+
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>training/enterprise/index.html">
             <span class="en">Developing for Enterprise</span>
@@ -278,7 +302,32 @@
           </a>
           </li>
         </ul>
-       </li>
+      </li>
+
+      <li class="toggle-list">
+        <div><a href="<?cs var:toroot ?>training/implementing-navigation/index.html">
+            <span class="en">Implementing Effective Navigation<span class="new">&nbsp;new!</span></span>
+          </a></div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/implementing-navigation/lateral.html">
+            <span class="en">Implementing Lateral Navigation</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/implementing-navigation/ancestral.html">
+            <span class="en">Implementing Ancestral Navigation</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/implementing-navigation/temporal.html">
+            <span class="en">Implementing Temporal Navigation</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/implementing-navigation/descendant.html">
+            <span class="en">Implementing Descendant Navigation</span>
+          </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>
diff --git a/docs/html/shareables/training/EffectiveNavigation.zip b/docs/html/shareables/training/EffectiveNavigation.zip
new file mode 100644
index 0000000..f21af45
--- /dev/null
+++ b/docs/html/shareables/training/EffectiveNavigation.zip
Binary files differ
diff --git a/docs/html/shareables/training/TabCompat.zip b/docs/html/shareables/training/TabCompat.zip
new file mode 100644
index 0000000..b70b442
--- /dev/null
+++ b/docs/html/shareables/training/TabCompat.zip
Binary files differ
diff --git a/docs/html/training/backward-compatible-ui/abstracting.jd b/docs/html/training/backward-compatible-ui/abstracting.jd
new file mode 100644
index 0000000..1141b54
--- /dev/null
+++ b/docs/html/training/backward-compatible-ui/abstracting.jd
@@ -0,0 +1,111 @@
+page.title=Abstracting the New APIs
+parent.title=Creating Backward-Compatible UIs
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Proxying to the New APIs
+next.link=new-implementation.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ul>
+  <li><a href="#prepare-abstraction">Prepare for Abstraction</a></li>
+  <li><a href="#create-abstract-tab">Create an Abstract Tab Interface</a></li>
+  <li><a href="#abstract-actionbar-tab">Abstract ActionBar.Tab</a></li>
+  <li><a href="#abstract-actionbar-methods">Abstract ActionBar Tab Methods</a></li>
+</ul>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
+  <li><a href="{@docRoot}guide/topics/ui/actionbar.html#Tabs">Action Bar Tabs</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/TabCompat.zip"
+  class="button">Download the sample app</a>
+<p class="filename">TabCompat.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Suppose you want to use <a href="{@docRoot}guide/topics/ui/actionbar.html#Tabs">action bar tabs</a> as the primary form of top-level navigation in your application. Unfortunately, the {@link android.app.ActionBar} APIs are only available in Android 3.0 or later (API level 11+). Thus, if you want to distribute your application to devices running earlier versions of the platform, you need to provide an implementation that supports the newer API while providing a fallback mechanism that uses older APIs.</p>
+
+<p>In this class, you build a tabbed user interface (UI) component that uses abstract classes with version-specific implementations to provide backward-compatibility. This lesson describes how to create an abstraction layer for the new tab APIs as the first step toward building the tab component.</p>
+
+<h2 id="prepare-abstraction">Prepare for Abstraction</h2>
+
+<p><a href="http://en.wikipedia.org/wiki/Abstraction_(computer_science)">Abstraction</a> in the Java programming language involves the creation of one or more interfaces or abstract classes to hide implementation details. In the case of newer Android APIs, you can use abstraction to build version-aware components that use the current APIs on newer devices, and fallback to older, more compatible APIs on older devices.</p>
+
+<p>When using this approach, you first determine what newer classes you want to be able to use in a backward compatible way, then create abstract classes, based on the public interfaces of the newer classes. In defining the abstraction interfaces, you should mirror the newer API as much as possible. This maximizes forward-compatibility and makes it easier to drop the abstraction layer in the future when it is no longer necessary.</p>
+
+<p>After creating abstract classes for these new APIs, any number of implementations can be created and chosen at runtime. For the purposes of backward-compatibility, these implementations can vary by required API level. Thus, one implementation may use recently released APIs, while others can use older APIs.</p>
+
+<h2 id="create-abstract-tab">Create an Abstract Tab Interface</h2>
+
+<p>In order to create a backward-compatible version of tabs, you should first determine which features and specific APIs your application requires. In the case of top-level section tabs, suppose you have the following functional requirements:</p>
+
+<ol>
+<li>Tab indicators should show text and an icon.</li>
+<li>Tabs can be associated with a fragment instance.</li>
+<li>The activity should be able to listen for tab changes.</li>
+</ol>
+
+<p>Preparing these requirements in advance allows you to control the scope of your abstraction layer. This means that you can spend less time creating multiple implementations of your abstraction layer and begin using your new backward-compatible implementation sooner.</p>
+
+<p>The key APIs for tabs are in {@link android.app.ActionBar} and {@link android.app.ActionBar.Tab ActionBar.Tab}. These are the APIs to abstract in order to make your tabs version-aware. The requirements for this example project call for compatibility back to Eclair (API level 5) while taking advantage of the new tab features in Honeycomb (API Level 11). A diagram of the class structure to support these two implementations and their abstract base classes (or interfaces) is shown below.</p>
+
+<img src="{@docRoot}images/training/backward-compatible-ui-classes.png"
+  alt="Class diagram of abstract base classes and version-specific implementations." id="figure-classes">
+
+<p class="img-caption"><strong>Figure 1.</strong> Class diagram of abstract base classes and version-specific implementations.</p>
+
+<h2 id="abstract-actionbar-tab">Abstract ActionBar.Tab</h2>
+
+<p>Get started on building your tab abstraction layer by creating an abstract class representing a tab, that mirrors the {@link android.app.ActionBar.Tab ActionBar.Tab} interface:</p>
+
+<pre>
+public abstract class CompatTab {
+    ...
+    public abstract CompatTab setText(int resId);
+    public abstract CompatTab setIcon(int resId);
+    public abstract CompatTab setTabListener(
+            CompatTabListener callback);
+    public abstract CompatTab setFragment(Fragment fragment);
+
+    public abstract CharSequence getText();
+    public abstract Drawable getIcon();
+    public abstract CompatTabListener getCallback();
+    public abstract Fragment getFragment();
+    ...
+}
+</pre>
+
+<p>You can use an abstract class instead of an interface here to simplify the implementation of common features such as association of tab objects with activities (not shown in the code snippet).</p>
+
+<h2 id="abstract-actionbar-methods">Abstract ActionBar Tab Methods</h2>
+
+<p>Next, define an abstract class that allows you to create and add tabs to an activity, like {@link android.app.ActionBar#newTab ActionBar.newTab()} and {@link android.app.ActionBar#addTab ActionBar.addTab()}:</p>
+
+<pre>
+public abstract class TabHelper {
+    ...
+
+    public CompatTab newTab(String tag) {
+        // This method is implemented in a later lesson.
+    }
+
+    public abstract void addTab(CompatTab tab);
+
+    ...
+}
+</pre>
+
+<p>In the next lessons, you create implementations for <code>TabHelper</code> and <code>CompatTab</code> that work across both older and newer platform versions.</p>
diff --git a/docs/html/training/backward-compatible-ui/index.jd b/docs/html/training/backward-compatible-ui/index.jd
new file mode 100644
index 0000000..7e27e68
--- /dev/null
+++ b/docs/html/training/backward-compatible-ui/index.jd
@@ -0,0 +1,57 @@
+page.title=Creating Backward-Compatible UIs
+
+trainingnavtop=true
+startpage=true
+next.title=Abstracting the New Implementation
+next.link=abstracting.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+
+<ul>
+  <li>API level 5</li>
+  <li><a href="{@docRoot}sdk/compatibility-library.html">The Android Support Package</a></li>
+</ul>
+
+<h2>You should also read</h2>
+
+<ul>
+  <li><a href="{@docRoot}resources/samples/ActionBarCompat/index.html">ActionBarCompat</a></li>
+  <li><a href="http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html">How to have your (Cup)cake and eat it too</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/TabCompat.zip"
+  class="button">Download the sample app</a>
+<p class="filename">TabCompat.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>This class demonstrates how to use UI components and APIs available in newer versions of Android in a backward-compatible way, ensuring that your application still runs on previous versions of the platform.</p>
+
+<p>Throughout this class, the new <a href="{@docRoot}guide/topics/ui/actionbar.html#Tabs">Action Bar Tabs</a> feature introduced in Android 3.0 (API level 11) serves as the guiding example, but you can apply these techniques to other UI components and API features.</p>
+
+<h2 id="lessons">Lessons</h2>
+
+
+<dl>
+  <dt><strong><a href="abstracting.html">Abstracting the New APIs</a></strong></dt>
+    <dd>Determine which features and APIs your application needs. Learn how to define application-specific, intermediary Java interfaces that abstract the implementation of the UI component to your application.</dd>
+
+  <dt><strong><a href="new-implementation.html">Proxying to the New APIs</a></strong></dt>
+    <dd>Learn how to create an implementation of your interface that uses newer APIs.</dd>
+
+  <dt><strong><a href="older-implementation.html">Creating an Implementation with Older APIs</a></strong></dt>
+    <dd>Learn how to create a custom implementation of your interface that uses older APIs.</dd>
+
+  <dt><strong><a href="using-component.html">Using the Version-Aware Component</a></strong></dt>
+    <dd>Learn how to choose an implementation to use at runtime, and begin using the interface in your application.</dd>
+</dl>
diff --git a/docs/html/training/backward-compatible-ui/new-implementation.jd b/docs/html/training/backward-compatible-ui/new-implementation.jd
new file mode 100644
index 0000000..5b8b51c
--- /dev/null
+++ b/docs/html/training/backward-compatible-ui/new-implementation.jd
@@ -0,0 +1,113 @@
+page.title=Proxying to the New APIs
+parent.title=Creating Backward-Compatible UIs
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Abstracting the New APIs
+previous.link=abstracting.html
+next.title=Creating an Implementation with Older APIs
+next.link=older-implementation.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ol>
+  <li><a href="#new-tabs">Implement Tabs Using New APIs</a></li>
+  <li><a href="#compattabhoneycomb">Implement CompatTabHoneycomb</a></li>
+  <li><a href="#tabhelperhoneycomb">Implement TabHelperHoneycomb</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
+  <li><a href="{@docRoot}guide/topics/ui/actionbar.html#Tabs">Action Bar Tabs</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/TabCompat.zip"
+  class="button">Download the sample app</a>
+<p class="filename">TabCompat.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>This lesson shows you how to subclass the <code>CompatTab</code> and <code>TabHelper</code> abstract classes and use new APIs. Your application can use this implementation on devices running a platform version that supports them.</p>
+
+<h2 id="new-tabs">Implement Tabs Using New APIs</h2>
+
+<p>The concrete classes for <code>CompatTab</code> and <code>TabHelper</code> that use newer APIs are a <em>proxy</em> implementation. Since the abstract classes defined in the previous lesson mirror the new APIs (class structure, method signatures, etc.), the concrete classes that use these newer APIs simply proxy method calls and their results.</p>
+
+<p>You can directly use newer APIs in these concrete classes&mdash;and not crash on earlier devices&mdash;because of lazy class loading. Classes are loaded and initialized on first access&mdash;instantiating the class or accessing one of its static fields or methods for the first time. Thus, as long as you don't instantiate the Honeycomb-specific implementations on pre-Honeycomb devices, the Dalvik VM won't throw any {@link java.lang.VerifyError} exceptions.</p>
+
+<p>A good naming convention for this implementation is to append the API level or platform version code name corresponding to the APIs required by the concrete classes. For example, the native tab implementation can be provided by <code>CompatTabHoneycomb</code> and <code>TabHelperHoneycomb</code> classes, since they rely on APIs available in Android 3.0 (API level 11) or later.</p>
+
+<img src="{@docRoot}images/training/backward-compatible-ui-classes-honeycomb.png"
+  alt="Class diagram for the Honeycomb implementation of tabs." id="figure-classes">
+
+<p class="img-caption"><strong>Figure 1.</strong> Class diagram for the Honeycomb implementation of tabs.</p>
+
+<h2 id="compattabhoneycomb">Implement CompatTabHoneycomb</h2>
+
+<p><code>CompatTabHoneycomb</code> is the implementation of the <code>CompatTab</code> abstract class that <code>TabHelperHoneycomb</code> uses to reference individual tabs. <code>CompatTabHoneycomb</code> simply proxies all method calls to its contained {@link android.app.ActionBar.Tab} object.</p>
+
+<p>Begin implementing <code>CompatTabHoneycomb</code> using the new {@link android.app.ActionBar.Tab ActionBar.Tab} APIs:</p>
+
+<pre>
+public class CompatTabHoneycomb extends CompatTab {
+    // The native tab object that this CompatTab acts as a proxy for.
+    ActionBar.Tab mTab;
+    ...
+
+    protected CompatTabHoneycomb(FragmentActivity activity, String tag) {
+        ...
+        // Proxy to new ActionBar.newTab API
+        mTab = activity.getActionBar().newTab();
+    }
+
+    public CompatTab setText(int resId) {
+        // Proxy to new ActionBar.Tab.setText API
+        mTab.setText(resId);
+        return this;
+    }
+
+    ...
+    // Do the same for other properties (icon, callback, etc.)
+}
+</pre>
+
+<h2 id="tabhelperhoneycomb">Implement TabHelperHoneycomb</h2>
+
+<p><code>TabHelperHoneycomb</code> is the implementation of the <code>TabHelper</code> abstract class that proxies method calls to an actual {@link android.app.ActionBar}, obtained from its contained {@link android.app.Activity}.</p>
+
+<p>Implement <code>TabHelperHoneycomb</code>, proxying method calls to the {@link android.app.ActionBar} API:</p>
+
+<pre>
+public class TabHelperHoneycomb extends TabHelper {
+    ActionBar mActionBar;
+    ...
+
+    protected void setUp() {
+        if (mActionBar == null) {
+            mActionBar = mActivity.getActionBar();
+            mActionBar.setNavigationMode(
+                    ActionBar.NAVIGATION_MODE_TABS);
+        }
+    }
+
+    public void addTab(CompatTab tab) {
+        ...
+        // Tab is a CompatTabHoneycomb instance, so its
+        // native tab object is an ActionBar.Tab.
+        mActionBar.addTab((ActionBar.Tab) tab.getTab());
+    }
+
+    // The other important method, newTab() is part of
+    // the base implementation.
+}
+</pre>
\ No newline at end of file
diff --git a/docs/html/training/backward-compatible-ui/older-implementation.jd b/docs/html/training/backward-compatible-ui/older-implementation.jd
new file mode 100644
index 0000000..5006123
--- /dev/null
+++ b/docs/html/training/backward-compatible-ui/older-implementation.jd
@@ -0,0 +1,126 @@
+page.title=Creating an Implementation with Older APIs
+parent.title=Creating Backward-Compatible UIs
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Proxying to the New APIs
+previous.link=new-implementation.html
+next.title=Using the Version-Aware Component
+next.link=using-component.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ol>
+  <li><a href="#decide-substitute">Decide on a Substitute Solution</a></li>
+  <li><a href="#older-tabs">Implement Tabs Using Older APIs</a></li>
+</ol>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/TabCompat.zip"
+  class="button">Download the sample app</a>
+<p class="filename">TabCompat.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p>This lesson discusses how to create an implementation that mirrors newer APIs yet supports older devices.</p>
+
+<h2 id="decide-substitute">Decide on a Substitute Solution</h2>
+
+<p>The most challenging task in using newer UI features in a backward-compatible way is deciding on and implementing an older (fallback) solution for older platform versions. In many cases, it's possible to fulfill the purpose of these newer UI components using older UI framework features. For example:</p>
+
+<ul>
+
+<li>
+<p>Action bars can be implemented using a horizontal {@link android.widget.LinearLayout} containing image buttons, either as custom title bars or as views in your activity layout. Overflow actions can be presented under the device <em>Menu</em> button.</p>
+</li>
+
+<li>
+<p>Action bar tabs can be implemented using a horizontal {@link android.widget.LinearLayout} containing buttons, or using the {@link android.widget.TabWidget} UI element.</p>
+</li>
+
+<li>
+<p>{@link android.widget.NumberPicker} and {@link android.widget.Switch} widgets can be implemented using {@link android.widget.Spinner} and {@link android.widget.ToggleButton} widgets, respectively.</p>
+</li>
+
+<li>
+<p>{@link android.widget.ListPopupWindow} and {@link android.widget.PopupMenu} widgets can be implemented using {@link android.widget.PopupWindow} widgets.</p>
+</li>
+
+</ul>
+
+<p>There generally isn't a one-size-fits-all solution for backporting newer UI components to older devices. Be mindful of the user experience: on older devices, users may not be familiar with newer design patterns and UI components. Give some thought as to how the same functionality can be delivered using familiar elements. In many cases this is less of a concern&mdash;if newer UI components are prominent in the application ecosystem (such as the action bar), or where the interaction model is extremely simple and intuitive (such as swipe views using a {@link android.support.v4.view.ViewPager}).</p>
+
+<h2 id="older-tabs">Implement Tabs Using Older APIs</h2>
+
+<p>To create an older implementation of action bar tabs, you can use a {@link android.widget.TabWidget} and {@link android.widget.TabHost} (although one can alternatively use horizontally laid-out {@link android.widget.Button} widgets). Implement this in classes called <code>TabHelperEclair</code> and <code>CompatTabEclair</code>, since this implementation uses APIs introduced no later than Android 2.0 (Eclair).</p>
+
+
+<img src="{@docRoot}images/training/backward-compatible-ui-classes-eclair.png"
+  alt="Class diagram for the Eclair implementation of tabs." id="figure-classes">
+
+<p class="img-caption"><strong>Figure 1.</strong> Class diagram for the Eclair implementation of tabs.</p>
+
+<p>The <code>CompatTabEclair</code> implementation stores tab properties such as the tab text and icon in instance variables, since there isn't an {@link android.app.ActionBar.Tab ActionBar.Tab} object available to handle this storage:</p>
+
+<pre>
+public class CompatTabEclair extends CompatTab {
+    // Store these properties in the instance,
+    // as there is no ActionBar.Tab object.
+    private CharSequence mText;
+    ...
+
+    public CompatTab setText(int resId) {
+        // Our older implementation simply stores this
+        // information in the object instance.
+        mText = mActivity.getResources().getText(resId);
+        return this;
+    }
+
+    ...
+    // Do the same for other properties (icon, callback, etc.)
+}
+</pre>
+
+<p>The <code>TabHelperEclair</code> implementation makes use of methods on the
+{@link android.widget.TabHost} widget for creating {@link android.widget.TabHost.TabSpec}
+objects and tab indicators:</p>
+
+<pre>
+public class TabHelperEclair extends TabHelper {
+    private TabHost mTabHost;
+    ...
+
+    protected void setUp() {
+        if (mTabHost == null) {
+            // Our activity layout for pre-Honeycomb devices
+            // must contain a TabHost.
+            mTabHost = (TabHost) mActivity.findViewById(
+                    android.R.id.tabhost);
+            mTabHost.setup();
+        }
+    }
+
+    public void addTab(CompatTab tab) {
+        ...
+        TabSpec spec = mTabHost
+                .newTabSpec(tag)
+                .setIndicator(tab.getText()); // And optional icon
+        ...
+        mTabHost.addTab(spec);
+    }
+
+    // The other important method, newTab() is part of
+    // the base implementation.
+}
+</pre>
+
+<p>You now have two implementations of <code>CompatTab</code> and <code>TabHelper</code>: one that works on devices running Android 3.0 or later and uses new APIs, and another that works on devices running Android 2.0 or later and uses older APIs. The next lesson discusses using these implementations in your application.</p>
diff --git a/docs/html/training/backward-compatible-ui/using-component.jd b/docs/html/training/backward-compatible-ui/using-component.jd
new file mode 100644
index 0000000..4bf7fa0
--- /dev/null
+++ b/docs/html/training/backward-compatible-ui/using-component.jd
@@ -0,0 +1,143 @@
+page.title=Using the Version-Aware Component
+parent.title=Creating Backward-Compatible UIs
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Creating an Implementation with Older APIs
+previous.link=older-implementation.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ol>
+  <li><a href="#switching-logic">Add the Switching Logic</a></li>
+  <li><a href="#layout">Create a Version-Aware Activity Layout</a></li>
+  <li><a href="#use-tabhelper">Use TabHelper in Your Activity</a></li>
+</ol>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/TabCompat.zip"
+  class="button">Download the sample app</a>
+<p class="filename">TabCompat.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Now that you have two implementations of <code>TabHelper</code> and <code>CompatTab</code>&mdash;one for Android 3.0 and later and one for earlier versions of the platform&mdash;it's time to do something with these implementations. This lesson discusses creating the logic for switching between these implementations, creating version-aware layouts, and finally using the backward-compatible UI component.</p>
+
+<h2 id="switching-logic">Add the Switching Logic</h2>
+
+<p>The <code>TabHelper</code> abstract class acts as a <a href="http://en.wikipedia.org/wiki/Factory_(software_concept)">factory</a> for creating version-appropriate <code>TabHelper</code> and <code>CompatTab</code> instances, based on the current device's platform version:</p>
+
+<pre>
+public abstract class TabHelper {
+    ...
+    // Usage is TabHelper.createInstance(activity)
+    public static TabHelper createInstance(FragmentActivity activity) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            return new TabHelperHoneycomb(activity);
+        } else {
+            return new TabHelperEclair(activity);
+        }
+    }
+
+    // Usage is mTabHelper.newTab("tag")
+    public CompatTab newTab(String tag) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            return new CompatTabHoneycomb(mActivity, tag);
+        } else {
+            return new CompatTabEclair(mActivity, tag);
+        }
+    }
+    ...
+}
+</pre>
+
+<h2 id="layout">Create a Version-Aware Activity Layout</h2>
+
+<p>The next step is to provide layouts for your activity that can support the two tab implementations. For the older implementation (<code>TabHelperEclair</code>), you need to ensure that your activity layout contains a {@link android.widget.TabWidget} and {@link android.widget.TabHost}, along with a container for tab contents:</p>
+
+<p><strong>res/layout/main.xml:</strong></p>
+
+<pre>
+&lt;!-- This layout is for API level 5-10 only. --&gt;
+&lt;TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabhost"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"&gt;
+
+    &lt;LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="5dp"&gt;
+
+        &lt;TabWidget
+            android:id="@android:id/tabs"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" /&gt;
+
+        &lt;FrameLayout
+            android:id="@android:id/tabcontent"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1" /&gt;
+
+    &lt;/LinearLayout&gt;
+&lt;/TabHost&gt;
+</pre>
+
+<p>For the <code>TabHelperHoneycomb</code> implementation, all you need is a {@link android.widget.FrameLayout} to contain the tab contents, since the tab indicators are provided by the {@link android.app.ActionBar}:</p>
+
+<p><strong>res/layout-v11/main.xml:</strong></p>
+
+<pre>
+&lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabcontent"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" /&gt;
+</pre>
+
+<p>At runtime, Android will decide which version of the <code>main.xml</code> layout to inflate depending on the platform version. This is the same logic shown in the previous section to determine which <code>TabHelper</code> implementation to use.</p>
+
+<h2 id="use-tabhelper">Use TabHelper in Your Activity</h2>
+
+<p>In your activity's {@link android.app.Activity#onCreate onCreate()} method, you can obtain a <code>TabHelper</code> object and add tabs with the following code:</p>
+
+<pre>
+{@literal @}Override
+public void onCreate(Bundle savedInstanceState) {
+    setContentView(R.layout.main);
+
+    TabHelper tabHelper = TabHelper.createInstance(this);
+    tabHelper.setUp();
+
+    CompatTab photosTab = tabHelper
+            .newTab("photos")
+            .setText(R.string.tab_photos);
+    tabHelper.addTab(photosTab);
+
+    CompatTab videosTab = tabHelper
+            .newTab("videos")
+            .setText(R.string.tab_videos);
+    tabHelper.addTab(videosTab);
+}
+</pre>
+
+<p>When running the application, this code inflates the correct activity layout and instantiates either a <code>TabHelperHoneycomb</code> or <code>TabHelperEclair</code> object. The concrete class that's actually used is opaque to the activity, since they share the common <code>TabHelper</code> interface.</p>
+
+<p>Below are two screenshots of this implementation running on an Android 2.3 and Android 4.0 device.</p>
+
+<img src="{@docRoot}images/training/backward-compatible-ui-gb.png"
+  alt="Example screenshot of tabs running on an Android 2.3 device (using TabHelperEclair)." width="200">
+
+<img src="{@docRoot}images/training/backward-compatible-ui-ics.png"
+  alt="Example screenshots of tabs running on an Android 4.0 device (using TabHelperHoneycomb)." width="200">
+
+<p class="img-caption"><strong>Figure 1.</strong> Example screenshots of backward-compatible tabs running on an Android 2.3 device (using <code>TabHelperEclair</code>) and an Android 4.0 device (using <code>TabHelperHoneycomb</code>).</p>
diff --git a/docs/html/training/implementing-navigation/ancestral.jd b/docs/html/training/implementing-navigation/ancestral.jd
new file mode 100644
index 0000000..495b45d
--- /dev/null
+++ b/docs/html/training/implementing-navigation/ancestral.jd
@@ -0,0 +1,124 @@
+page.title=Implementing Ancestral Navigation
+parent.title=Implementing Effective Navigation
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Implementing Lateral Navigation
+previous.link=lateral.html
+next.title=Implementing Temporal Navigation
+next.link=temporal.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ol>
+  <li><a href="#up">Implement <em>Up</em> Navigation</a></li>
+  <li><a href="#app-home">Properly Handle the Application Home Screen</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li>
+  <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
+  <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip"
+  class="button">Download the sample app</a>
+<p class="filename">EffectiveNavigation.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p><em>Ancestral navigation</em> is up the application's information hierarchy, where the top of the hierarchy (or root) is the application's home screen. This navigation concept is described in <a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Designing Effective Navigation</a>. This lesson discusses how to provide ancestral navigation using the <em>Up</em> button in the action bar.</p>
+
+
+<h2 id="up">Implement <em>Up</em> Navigation</h2>
+
+<p>When implementing ancestral navigation, all screens in your application that aren't the home screen should offer a means of navigating to the immediate parent screen in the hierarchy via the <em>Up</em> button in the action bar.</p>
+
+
+<img src="{@docRoot}images/training/implementing-navigation-up.png"
+  alt="The Up button in the action bar." id="figure-up">
+
+<p class="img-caption"><strong>Figure 1.</strong> The <em>Up</em> button in the action bar.</p>
+
+<p>Regardless of how the current screen was reached, pressing this button should always take the user to the same screen in the hierarchy.</p>
+
+<p>To implement <em>Up</em>, enable it in the action bar in your activity's {@link android.app.Activity#onCreate onCreate()} method:</p>
+
+<pre>
+{@literal @}Override
+public void onCreate(Bundle savedInstanceState) {
+    ...
+    getActionBar().setDisplayHomeAsUpEnabled(true);
+    ...
+}
+</pre>
+
+<p>You should also handle <code>android.R.id.home</code> in {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}. This resource is the menu item ID for the <em>Home</em> (or <em>Up</em>) button. To ensure that a specific parent activity is shown, <em>DO NOT</em> simply call {@link android.app.Activity#finish finish()}. Instead, use an intent such as the one described below.</p>
+
+<pre>
+{@literal @}Override
+public boolean onOptionsItemSelected(MenuItem item) {
+    switch (item.getItemId()) {
+        case android.R.id.home:
+            // This is called when the Home (Up) button is pressed
+            // in the Action Bar.
+            Intent parentActivityIntent = new Intent(this, MyParentActivity.class);
+            parentActivityIntent.addFlags(
+                    Intent.FLAG_ACTIVITY_CLEAR_TOP |
+                    Intent.FLAG_ACTIVITY_NEW_TASK);
+            startActivity(parentActivityIntent);
+            finish();
+            return true;
+    }
+    return super.onOptionsItemSelected(item);
+}
+</pre>
+
+<p>When the current activity belongs to a task from a different application&mdash;for example if it was reached via an intent from another application&mdash;pressing <em>Up</em> should create a new task for the application with a synthesized back stack. This approach is described in <a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a> and the {@link android.support.v4.app.TaskStackBuilder} class reference.</p>
+
+<p>The {@link android.support.v4.app.NavUtils} and {@link android.support.v4.app.TaskStackBuilder} classes in the <a href="{@docRoot}sdk/compatibility-library.html">Android Support Package</a> provide helpers for implementing this behavior correctly. An example usage of these two helper classes is below:</p>
+
+<pre>
+{@literal @}Override
+public boolean onOptionsItemSelected(MenuItem item) {
+    switch (item.getItemId()) {
+        case android.R.id.home:
+            Intent upIntent = new Intent(this, MyParentActivity.class);
+            if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
+                // This activity is not part of the application's task, so create a new task
+                // with a synthesized back stack.
+                TaskStackBuilder.from(this)
+                        .addNextIntent(new Intent(this, MyGreatGrandParentActivity.class))
+                        .addNextIntent(new Intent(this, MyGrandParentActivity.class))
+                        .addNextIntent(upIntent)
+                        .startActivities();
+                finish();
+            } else {
+                // This activity is part of the application's task, so simply
+                // navigate up to the hierarchical parent activity.
+                NavUtils.navigateUpTo(this, upIntent);
+            }
+            return true;
+    }
+    return super.onOptionsItemSelected(item);
+}
+</pre>
+
+<h2 id="app-home">Properly Handle the Application Home Screen</h2>
+
+<p>By default, the <em>Home</em> button in the action bar is interactive. Since it does not make much sense to navigate home&mdash;or up one level&mdash;while on the home screen, you should disable the button like so:</p>
+
+<pre>
+getActionBar().setHomeButtonEnabled(false);
+</pre>
diff --git a/docs/html/training/implementing-navigation/descendant.jd b/docs/html/training/implementing-navigation/descendant.jd
new file mode 100644
index 0000000..7d0063c
--- /dev/null
+++ b/docs/html/training/implementing-navigation/descendant.jd
@@ -0,0 +1,65 @@
+page.title=Implementing Descendant Navigation
+parent.title=Implementing Effective Navigation
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Implementing Temporal Navigation
+previous.link=temporal.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ol>
+  <li><a href="#master-detail">Implement Master/Detail Flows Across Handsets and Tablets</a></li>
+  <li><a href="#external-activities">Navigate into External Activities</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}training/design-navigation/descendant-lateral.html">Providing Descendant and Lateral Navigation</a></li>
+  <li><a href="{@docRoot}design/patterns/app-structure.html">Android Design: App Structure</a></li>
+  <li><a href="{@docRoot}design/patterns/multi-pane-layouts.html">Android Design: Multi-pane Layouts</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip"
+  class="button">Download the sample app</a>
+<p class="filename">EffectiveNavigation.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p><em>Descendant navigation</em> is navigation down the application's information hierarchy. This is described in <a href="{@docRoot}training/design-navigation/descendant-lateral.html">Designing Effective Navigation</a> and also covered in <a href="{@docRoot}design/patterns/app-structure.html">Android Design: Application Structure</a>.</p>
+
+<p>Descendant navigation is usually implemented using {@link android.content.Intent} objects and {@link android.content.Context#startActivity startActivity()}, or by adding fragments to an activity using {@link android.app.FragmentTransaction} objects. This lesson covers other interesting cases that arise when implementing descendant navigation.</p>
+
+<h2 id="master-detail">Implement Master/Detail Flows Across Handsets and Tablets</h2>
+
+<p>In a <em>master/detail</em> navigation flow, a <em>master</em> screen contains a list of items in a collection, and a <em>detail</em> screen shows detailed information about a specific item within that collection. Implementing navigation from the master screen to the detail screen is one form of descendant navigation.</p>
+
+<p>Handset touchscreens are most suitable for displaying one screen at a time (either the master or the detail screen); this concern is further discussed in <a href="{@docRoot}training/design-navigation/multiple-sizes.html">Planning for Multiple Touchscreen Sizes</a>. Descendant navigation in this case is often implemented using an {@link android.content.Intent} that starts an activity representing the detail screen. On the other hand, tablet displays, especially when viewed in the landscape orientation, are best suited for showing multiple content panes at a time: the master on the left, and the detail to the right). Here, descendant navigation is usually implemented using a {@link android.app.FragmentTransaction} that adds, removes, or replaces the detail pane with new content.</p>
+
+<p>The basics of implementing this pattern are described in the <a href="{@docRoot}training/multiscreen/adaptui.html">Implementing Adaptive UI Flows</a> lesson of the <em>Designing for Multiple Screens</em> class. The class describes how to implement a master/detail flow using two activities on a handset and a single activity on a tablet.</p>
+
+<h2 id="external-activities">Navigate into External Activities</h2>
+
+<p>There are cases where descending into your application's information hierarchy leads to activities from other applications. For example, when viewing the contact details screen for an entry in the phone address book, a child screen detailing recent posts by the contact on a social network may belong to a social networking application.</p>
+
+<p>When launching another application's activity to allow the user to say, compose an email or pick a photo attachment, you generally don't want the user to return to this activity if they relaunch your application from the Launcher (the device home screen). It would be confusing if touching your application icon brought the user to a "compose email" screen.</p>
+
+<p>To prevent this from occurring, simply add the {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET} flag to the intent used to launch the external activity, like so:</p>
+
+<pre>
+Intent externalActivityIntent = new Intent(Intent.ACTION_PICK);
+externalActivityIntent.setType("image/*");
+externalActivityIntent.addFlags(
+        Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+startActivity(externalActivityIntent);
+</pre>
diff --git a/docs/html/training/implementing-navigation/index.jd b/docs/html/training/implementing-navigation/index.jd
new file mode 100644
index 0000000..da61c81
--- /dev/null
+++ b/docs/html/training/implementing-navigation/index.jd
@@ -0,0 +1,68 @@
+page.title=Implementing Effective Navigation
+
+trainingnavtop=true
+startpage=true
+next.title=Implementing Lateral Navigation
+next.link=lateral.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+
+<ul>
+  <li>API level 14</li>
+  <li>Understanding of fragments and Android layouts</li>
+  <li><a href="{@docRoot}sdk/compatibility-library.html">The Android Support Package</a></li>
+  <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
+</ul>
+
+<h2>You should also read</h2>
+
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
+  <li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a></li>
+  <li><a href="{@docRoot}training/multiscreen/index.html">Designing for Multiple Screens</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip"
+  class="button">Download the sample app</a>
+<p class="filename">EffectiveNavigation.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p>This class demonstrates how to implement the key navigation design patterns detailed in the
+<a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a> class.
+The lessons in this class cover implementing navigation up, down, and across your application's <a
+href="{@docRoot}training/design-navigation/screen-planning.html#diagram- relationships">screen
+map</a>.</p>
+
+<p>After reading through the lessons in this class and exploring the associated sample application
+(see right), you should also have a basic understanding of how to use
+{@link android.app.ActionBar} and {@link android.support.v4.view.ViewPager}, two components that are fundamental to core app navigation.</p>
+
+
+<h2 id="lessons">Lessons</h2>
+
+
+<dl>
+  <dt><strong><a href="lateral.html">Implementing Lateral Navigation</a></strong></dt>
+    <dd>Learn how to implement tabs and horizontal paging (swipe views).</dd>
+
+  <dt><strong><a href="ancestral.html">Implementing Ancestral Navigation</a></strong></dt>
+    <dd>Learn how to implement <em>Up</em> navigation.</dd>
+
+  <dt><strong><a href="temporal.html">Implementing Temporal Navigation</a></strong></dt>
+    <dd>Learn how to correctly handle the <em>Back</em> button.</dd>
+
+  <dt><strong><a href="descendant.html">Implementing Descendant Navigation</a></strong></dt>
+    <dd>Learn the finer points of implementing navigation into your application's information hierarchy.</dd>
+</dl>
diff --git a/docs/html/training/implementing-navigation/lateral.jd b/docs/html/training/implementing-navigation/lateral.jd
new file mode 100644
index 0000000..d9ba5c9
--- /dev/null
+++ b/docs/html/training/implementing-navigation/lateral.jd
@@ -0,0 +1,252 @@
+page.title=Implementing Lateral Navigation
+parent.title=Implementing Effective Navigation
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Implementing Ancestral Navigation
+next.link=ancestral.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#tabs">Implement Tabs</a></li>
+  <li><a href="#horizontal-paging">Implement Horizontal Paging (Swipe Views)</a></li>
+  <li><a href="#swipe-tabs">Implement Swiping Between Tabs</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}training/design-navigation/descendant-lateral.html">Providing Descendant and Lateral Navigation</a></li>
+  <li><a href="{@docRoot}design/building-blocks/tabs.html">Android Design: Tabs</a></li>
+  <li><a href="{@docRoot}design/patterns/swipe-views.html">Android Design: Swipe Views</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+<a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip"
+  class="button">Download the sample app</a>
+<p class="filename">EffectiveNavigation.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p><em>Lateral navigation</em> is navigation between sibling screens in the application's screen hierarchy (sometimes referred to as a screen map). The most prominent lateral navigation patterns are tabs and horizontal paging (also known as swipe views). This pattern and others are described in <a href="{@docRoot}training/design-navigation/descendant-lateral.html">Designing Effective Navigation</a>. This lesson covers how to implement several of the primary lateral navigation patterns in Android.</p>
+
+<h2 id="tabs">Implement Tabs</h2>
+
+<p>Tabs allow the user to navigate between sibling screens by selecting the appropriate tab indicator available at the top of the display. In Android 3.0 and later, tabs are implemented using the {@link android.app.ActionBar} class, and are generally set up in {@link android.app.Activity#onCreate Activity.onCreate()}. In some cases, such as when horizontal space is limited and/or the number of tabs is large, an appropriate alternate presentation for tabs is a dropdown list (sometimes implemented using a {@link android.widget.Spinner}).</p>
+
+<p>In previous versions of Android, tabs could be implemented using a {@link android.widget.TabWidget} and {@link android.widget.TabHost}. For details, see the <a href="{@docRoot}resources/tutorials/views/hello-tabwidget.html">Hello, Views</a> tutorial.</p>
+
+<p>As of Android 3.0, however, you should use either {@link android.app.ActionBar#NAVIGATION_MODE_TABS} or {@link android.app.ActionBar#NAVIGATION_MODE_LIST} along with the {@link android.app.ActionBar} class.</p>
+
+<h3>Implement the Tabs Pattern with NAVIGATION_MODE_TABS</h3>
+
+<p>To create tabs, you can use the following code in your activity's {@link android.app.Activity#onCreate onCreate()} method. Note that the exact presentation of tabs may vary per device and by the current device configuration, to make best use of available screen space. For example, Android may automatically collapse tabs into a dropdown list if tabs don't fit horizontally in the action bar.</p>
+
+<pre>
+{@literal @}Override
+public void onCreate(Bundle savedInstanceState) {
+    ...
+    final ActionBar actionBar = getActionBar();
+
+    // Specify that tabs should be displayed in the action bar.
+    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+
+    // Create a tab listener that is called when the user changes tabs.
+    ActionBar.TabListener tabListener = new ActionBar.TabListener() {
+        public void onTabSelected(ActionBar.Tab tab,
+                FragmentTransaction ft) { }
+
+        public void onTabUnselected(ActionBar.Tab tab,
+                FragmentTransaction ft) { }
+
+        public void onTabReselected(ActionBar.Tab tab,
+                FragmentTransaction ft) { }
+    };
+
+    // Add 3 tabs.
+    for (int i = 0; i &lt; 3; i++) {
+        actionBar.addTab(
+                actionBar.newTab()
+                        .setText("Tab " + (i + 1))
+                        .setTabListener(tabListener));
+    }
+    ...
+}
+</pre>
+
+<h3>Implement the Tabs Pattern with NAVIGATION_MODE_LIST</h3>
+
+<p>To use a dropdown list instead, use the following code in your activity's {@link android.app.Activity#onCreate onCreate()} method. Dropdown lists are often preferable in cases where more information must be shown per navigation item, such as unread message counts, or where the number of available navigation items is large.</p>
+
+<pre>
+{@literal @}Override
+public void onCreate(Bundle savedInstanceState) {
+    ...
+    final ActionBar actionBar = getActionBar();
+
+    // Specify that a dropdown list should be displayed in the action bar.
+    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+
+    actionBar.setListNavigationCallbacks(
+            // Specify a SpinnerAdapter to populate the dropdown list.
+            new ArrayAdapter<String>(
+                    actionBar.getThemedContext(),
+                    android.R.layout.simple_list_item_1,
+                    android.R.id.text1,
+                    new String[]{ "Tab 1", "Tab 2", "Tab 3" }),
+
+            // Provide a listener to be called when an item is selected.
+            new ActionBar.OnNavigationListener() {
+                public boolean onNavigationItemSelected(
+                        int position, long id) {
+                    // Take action here, e.g. switching to the
+                    // corresponding fragment.
+                    return true;
+                }
+            });
+    ...
+}
+</pre>
+
+<h2 id="horizontal-paging">Implement Horizontal Paging (Swipe Views)</h2>
+
+<p>Horizontal paging, or swipe views, allow users to <a href="{@docRoot}design/patterns/swipe-views">swipe</a> horizontally on the current screen to navigate to adjacent screens. This pattern can be implemented using the {@link android.support.v4.view.ViewPager} widget, currently available as part of the <a href="{@docRoot}sdk/compatibility-library.html">Android Support Package</a>. For navigating between sibling screens representing a fixed number of sections, it's best to provide the {@link android.support.v4.view.ViewPager} with a {@link android.support.v4.app.FragmentPagerAdapter}. For horizontal paging across collections of objects, it's best to use a {@link android.support.v4.app.FragmentStatePagerAdapter}, which destroys fragments as the user navigates to other pages, minimizing memory usage.</p>
+
+<p>Below is an example of using a {@link android.support.v4.view.ViewPager} to swipe across a collection of objects.</p>
+
+<pre>
+public class CollectionDemoActivity extends FragmentActivity {
+    // When requested, this adapter returns a DemoObjectFragment,
+    // representing an object in the collection.
+    DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
+    ViewPager mViewPager;
+
+    public void onCreate(Bundle savedInstanceState) {
+        // ViewPager and its adapters use support library
+        // fragments, so use getSupportFragmentManager.
+        mDemoCollectionPagerAdapter =
+                new DemoCollectionPagerAdapter(
+                        getSupportFragmentManager());
+        mViewPager = (ViewPager) findViewById(R.id.pager);
+        mViewPager.setAdapter(mDemoCollectionPagerAdapter);
+    }
+}
+
+// Since this is an object collection, use a FragmentStatePagerAdapter,
+// and NOT a FragmentPagerAdapter.
+public class DemoCollectionPagerAdapter extends
+        FragmentStatePagerAdapter {
+    public DemoCollectionPagerAdapter(FragmentManager fm) {
+        super(fm);
+    }
+
+    {@literal @}Override
+    public Fragment getItem(int i) {
+        Fragment fragment = new DemoObjectFragment();
+        Bundle args = new Bundle();
+        // Our object is just an integer :-P
+        args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    {@literal @}Override
+    public int getCount() {
+        return 100;
+    }
+
+    {@literal @}Override
+    public CharSequence getPageTitle(int position) {
+        return "OBJECT " + (position + 1);
+    }
+}
+
+// Instances of this class are fragments representing a single
+// object in our collection.
+public static class DemoObjectFragment extends Fragment {
+    public static final String ARG_OBJECT = "object";
+
+    {@literal @}Override
+    public View onCreateView(LayoutInflater inflater,
+            ViewGroup container, Bundle savedInstanceState) {
+        // The last two arguments ensure LayoutParams are inflated
+        // properly.
+        View rootView = inflater.inflate(
+                R.layout.fragment_collection_object, container, false);
+        Bundle args = getArguments();
+        ((TextView) rootView.findViewById(android.R.id.text1)).setText(
+                Integer.toString(args.getInt(ARG_OBJECT)));
+        return rootView;
+    }
+}
+</pre>
+
+<p>You can also add indicators to your horizontal paging UI by adding a {@link android.support.v4.view.PagerTitleStrip}. Below is an example layout XML file for an activity whose entire contents are a {@link android.support.v4.view.ViewPager} and a top-aligned {@link android.support.v4.view.PagerTitleStrip} inside it. Individual pages (provided by the adapter) occupy the remaining space inside the {@link android.support.v4.view.ViewPager}.</p>
+
+<pre>
+&lt;android.support.v4.view.ViewPager
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/pager"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"&gt;
+
+    &lt;android.support.v4.view.PagerTitleStrip
+        android:id="@+id/pager_title_strip"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:background="#33b5e5"
+        android:textColor="#fff"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp" /&gt;
+
+&lt;/android.support.v4.view.ViewPager&gt;
+</pre>
+
+<h2 id="swipe-tabs">Implement Swiping Between Tabs</h2>
+
+<p>One of the key design recommendations in Android 4.0 for tabs is to <a href="{@docRoot}design/patterns/swipe-views.html">allow swiping</a> between them where appropriate. This behavior enables users to swipe horizontally across the selected tab's contents to navigate to adjacent tabs, without needed to directly interact with the tabs themselves. To implement this, you can use a {@link android.support.v4.view.ViewPager} in conjunction with the {@link android.app.ActionBar} tabs API.</p>
+
+<p>Upon observing the current page changing, select the corresponding tab. You can set up this behavior using an {@link android.support.v4.view.ViewPager.OnPageChangeListener} in your activity's {@link android.app.Activity#onCreate onCreate()} method:</p>
+
+<pre>
+{@literal @}Override
+public void onCreate(Bundle savedInstanceState) {
+    ...
+    mViewPager.setOnPageChangeListener(
+            new ViewPager.SimpleOnPageChangeListener() {
+                {@literal @}Override
+                public void onPageSelected(int position) {
+                    // When swiping between pages, select the
+                    // corresponding tab.
+                    getActionBar().setSelectedNavigationItem(position);
+                }
+            });
+    ...
+}
+</pre>
+
+<p>And upon selecting a tab, switch to the corresponding page in the {@link android.support.v4.view.ViewPager}. To do this, add an {@link android.app.ActionBar.TabListener} to your tab when creating it using the {@link android.app.ActionBar#newTab newTab()} method:</p>
+
+<pre>
+actionBar.newTab()
+        ...
+        .setTabListener(new ActionBar.TabListener() {
+            public void onTabSelected(ActionBar.Tab tab,
+                    FragmentTransaction ft) {
+                // When the tab is selected, switch to the
+                // corresponding page in the ViewPager.
+                mViewPager.setCurrentItem(tab.getPosition());
+            }
+            ...
+        }));
+</pre>
diff --git a/docs/html/training/implementing-navigation/temporal.jd b/docs/html/training/implementing-navigation/temporal.jd
new file mode 100644
index 0000000..f36991f
--- /dev/null
+++ b/docs/html/training/implementing-navigation/temporal.jd
@@ -0,0 +1,83 @@
+page.title=Implementing Temporal Navigation
+parent.title=Implementing Effective Navigation
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Implementing Ancestral Navigation
+previous.link=ancestral.html
+next.title=Implementing Descendant Navigation
+next.link=descendant.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to:</h2>
+<ol>
+  <li><a href="#back-fragments">Implement <em>Back</em> Navigation with Fragments</a></li>
+  <li><a href="#back-webviews">Implement <em>Back</em> Navigation with WebViews</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li>
+  <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
+  <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p><em>Temporal navigation</em> is navigation to previously visited screens. Users can visit previous screens by pressing the device <em>Back</em> button. This user interface pattern is described further in <a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a> in <em>Designing Effective Navigation</em> and in <a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a>.</p>
+
+<p>Android handles basic <em>Back</em> navigation for you (see <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> for details on this behavior). This lesson discusses a number of cases where applications should provide specialized logic for the <em>Back</em> button.</p>
+
+
+<h2 id="back-fragments">Implement <em>Back</em> Navigation with Fragments</h2>
+
+<p>When using fragments in your application, individual {@link android.app.FragmentTransaction} objects can represent context changes that should be added to the back stack. For example, if you are implementing a <a href="descendant.html#master-detail">master/detail flow</a> on a handset by swapping out fragments (thus emulating a {@link android.app.Activity#startActivity startActivity()} call), you should ensure that pressing the <em>Back</em> button on a detail screen returns the user to the master screen. To do so, you can use {@link android.app.FragmentTransaction#addToBackStack addToBackStack()}:</p>
+
+<pre>
+// Works with either the framework FragmentManager or the
+// support package FragmentManager (getSupportFragmentManager).
+getFragmentManager().beginTransaction()
+        .add(detailFragment, "detail")
+
+        // Add this transaction to the back stack and commit.
+        .addToBackStack()
+        .commit();
+</pre>
+
+<p>The activity's {@link android.app.FragmentManager} handles <em>Back</em> button presses if there are {@link android.app.FragmentTransaction} objects on the back stack. When this happens, the {@link android.app.FragmentManager} pops the most recent transaction off the back stack and performs the reverse action (e.g., removing a fragment if the transaction added it).</p>
+
+<p>If your application updates other user interface elements to reflect the current state of your fragments, such as the action bar, remember to update the UI when you commit the transaction. You should update your user interface after the fragment manager back stack changes in addition to when you commit the transaction. You can listen for when a <code>FragmentTransaction</code> is reverted by setting up an {@link android.app.FragmentManager.OnBackStackChangedListener}:</p>
+
+<pre>
+getFragmentManager().addOnBackStackChangedListener(
+        new FragmentManager.OnBackStackChangedListener() {
+            public void onBackStackChanged() {
+                // Update your UI here.
+            }
+        });
+</pre>
+
+<h2 id="back-webviews">Implement <em>Back</em> Navigation with WebViews</h2>
+
+<p>If a part of your application is contained in a {@link android.webkit.WebView}, it may be appropriate for <em>Back</em> to traverse browser history. To do so, you can override {@link android.app.Activity#onBackPressed onBackPressed()} and proxy to the <code>WebView</code> if it has history state:</p>
+
+<pre>
+{@literal @}Override
+public void onBackPressed() {
+    if (mWebView.canGoBack()) {
+        mWebView.goBack();
+        return;
+    }
+
+    // Otherwise defer to system default behavior.
+    super.onBackPressed();
+}
+</pre>
+
+<p>Be careful when using this mechanism with highly dynamic web pages that can grow a large history. Pages that generate an extensive history, such as those that make frequent changes to the document hash, may make it tedious for users to get out of your activity.</p>
diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h
index 2eac544..38203af 100644
--- a/include/androidfw/InputDevice.h
+++ b/include/androidfw/InputDevice.h
@@ -93,6 +93,9 @@
         return mKeyCharacterMap;
     }
 
+    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
+    inline bool hasVibrator() const { return mHasVibrator; }
+
     inline const Vector<MotionRange>& getMotionRanges() const {
         return mMotionRanges;
     }
@@ -105,6 +108,7 @@
     uint32_t mSources;
     int32_t mKeyboardType;
     sp<KeyCharacterMap> mKeyCharacterMap;
+    bool mHasVibrator;
 
     Vector<MotionRange> mMotionRanges;
 };
diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp
index 6bb06a9..d6c49f7 100644
--- a/libs/androidfw/InputDevice.cpp
+++ b/libs/androidfw/InputDevice.cpp
@@ -136,6 +136,7 @@
         mSources(other.mSources),
         mKeyboardType(other.mKeyboardType),
         mKeyCharacterMap(other.mKeyCharacterMap),
+        mHasVibrator(other.mHasVibrator),
         mMotionRanges(other.mMotionRanges) {
 }
 
@@ -150,6 +151,7 @@
     mDescriptor = descriptor;
     mSources = 0;
     mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
+    mHasVibrator = false;
     mMotionRanges.clear();
 }
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 56826fa..1654eca 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Kennisgewings"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-verbind"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Stel invoer metodes op"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fisiese sleutelbord"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Laat die program <xliff:g id="APPLICATION">%1$s</xliff:g> toe om toegang tot die USB-toestel te kry?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Laat die program <xliff:g id="APPLICATION">%1$s</xliff:g> toe om toegang tot die USB-toebehoorsel te kry?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Maak <xliff:g id="ACTIVITY">%1$s</xliff:g> oop wanneer hierdie USB-toestel gekoppel is?"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index b885503..433c124 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Паведамленні"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Прывязаныя праз Bluetooth"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налада метадаў уводу"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Фізічная клавіятура"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Дазволіць праыкладанню <xliff:g id="APPLICATION">%1$s</xliff:g> атрымлiваць доступ да прылады USB?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Дазволіць прыкладанню <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Адкрыць <xliff:g id="ACTIVITY">%1$s</xliff:g>, калі гэтая USB-прылада падлучаная?"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ac58b061..6c614cd 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Underretninger"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysisk tastatur"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Tillad, at appen <xliff:g id="APPLICATION">%1$s</xliff:g> kan få adgang til USB-enheden?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vil du tillade, at appen <xliff:g id="APPLICATION">%1$s</xliff:g> får adgang til USB-enheden?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åbne <xliff:g id="ACTIVITY">%1$s</xliff:g>, når denne USB-enhed er tilsluttet?"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 148924a..b20a5f3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 8e3a1e3..055e3ee 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Teatised"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth on jagatud"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Seadista sisestusmeetodeid"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Füüsiline klaviatuur"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Kas lubate rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> USB-seadmele juurde pääseda?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Kas lubate rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> USB-seadmele juurde pääseda?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Kas avada <xliff:g id="ACTIVITY">%1$s</xliff:g>, kui see USB-seade on ühendatud?"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1a8c6a7..c7f307c 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Connexion Bluetooth partagée"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurer les modes de saisie"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Clavier physique"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder au périphérique USB ?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à l\'accessoire USB ?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de ce périphérique USB ?"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index cdf7c9d..a725377 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -48,8 +48,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifiche"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth con tethering"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura metodi di immissione"</string>
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastiera fisica"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere al dispositivo USB?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere all\'accessorio USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Aprire <xliff:g id="ACTIVITY">%1$s</xliff:g> quando questo dispositivo USB è collegato?"</string>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0a63840..897b8d0 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -909,7 +909,7 @@
             mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
         }
 
-        mVibrator = new Vibrator();
+        mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mLongPressVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_longPressVibePattern);
         mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(),
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index fbffc94..c0eb1b9 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -161,12 +161,14 @@
         const InputDeviceIdentifier& identifier) :
         next(NULL),
         fd(fd), id(id), path(path), identifier(identifier),
-        classes(0), configuration(NULL), virtualKeyMap(NULL) {
+        classes(0), configuration(NULL), virtualKeyMap(NULL),
+        ffEffectPlaying(false), ffEffectId(-1) {
     memset(keyBitmask, 0, sizeof(keyBitmask));
     memset(absBitmask, 0, sizeof(absBitmask));
     memset(relBitmask, 0, sizeof(relBitmask));
     memset(swBitmask, 0, sizeof(swBitmask));
     memset(ledBitmask, 0, sizeof(ledBitmask));
+    memset(ffBitmask, 0, sizeof(ffBitmask));
     memset(propBitmask, 0, sizeof(propBitmask));
 }
 
@@ -534,6 +536,62 @@
     return NULL;
 }
 
+void EventHub::vibrate(int32_t deviceId, nsecs_t duration) {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && !device->isVirtual()) {
+        ff_effect effect;
+        memset(&effect, 0, sizeof(effect));
+        effect.type = FF_RUMBLE;
+        effect.id = device->ffEffectId;
+        effect.u.rumble.strong_magnitude = 0xc000;
+        effect.u.rumble.weak_magnitude = 0xc000;
+        effect.replay.length = (duration + 999999LL) / 1000000LL;
+        effect.replay.delay = 0;
+        if (ioctl(device->fd, EVIOCSFF, &effect)) {
+            ALOGW("Could not upload force feedback effect to device %s due to error %d.",
+                    device->identifier.name.string(), errno);
+            return;
+        }
+        device->ffEffectId = effect.id;
+
+        struct input_event ev;
+        ev.time.tv_sec = 0;
+        ev.time.tv_usec = 0;
+        ev.type = EV_FF;
+        ev.code = device->ffEffectId;
+        ev.value = 1;
+        if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
+            ALOGW("Could not start force feedback effect on device %s due to error %d.",
+                    device->identifier.name.string(), errno);
+            return;
+        }
+        device->ffEffectPlaying = true;
+    }
+}
+
+void EventHub::cancelVibrate(int32_t deviceId) {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && !device->isVirtual()) {
+        if (device->ffEffectPlaying) {
+            device->ffEffectPlaying = false;
+
+            struct input_event ev;
+            ev.time.tv_sec = 0;
+            ev.time.tv_usec = 0;
+            ev.type = EV_FF;
+            ev.code = device->ffEffectId;
+            ev.value = 0;
+            if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
+                ALOGW("Could not stop force feedback effect on device %s due to error %d.",
+                        device->identifier.name.string(), errno);
+                return;
+            }
+        }
+    }
+}
+
 EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
     if (deviceId == BUILT_IN_KEYBOARD_ID) {
         deviceId = mBuiltInKeyboardId;
@@ -949,6 +1007,7 @@
     ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask);
     ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask);
     ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask);
+    ioctl(fd, EVIOCGBIT(EV_FF, sizeof(device->ffBitmask)), device->ffBitmask);
     ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask);
 
     // See if this is a keyboard.  Ignore everything in the button range except for
@@ -1010,6 +1069,11 @@
         }
     }
 
+    // Check whether this device supports the vibrator.
+    if (test_bit(FF_RUMBLE, device->ffBitmask)) {
+        device->classes |= INPUT_DEVICE_CLASS_VIBRATOR;
+    }
+
     // Configure virtual keys.
     if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
         // Load the virtual keys for the touch screen, if any.
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 88159e7..51d2bac 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -113,6 +113,9 @@
     /* The input device is a joystick (implies gamepad, has joystick absolute axes). */
     INPUT_DEVICE_CLASS_JOYSTICK      = 0x00000100,
 
+    /* The input device has a vibrator (supports FF_RUMBLE). */
+    INPUT_DEVICE_CLASS_VIBRATOR      = 0x00000200,
+
     /* The input device is virtual (not a real device, not part of UI configuration). */
     INPUT_DEVICE_CLASS_VIRTUAL       = 0x40000000,
 
@@ -219,6 +222,10 @@
 
     virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0;
 
+    /* Control the vibrator. */
+    virtual void vibrate(int32_t deviceId, nsecs_t duration) = 0;
+    virtual void cancelVibrate(int32_t deviceId) = 0;
+
     /* Requests the EventHub to reopen all input devices on the next call to getEvents(). */
     virtual void requestReopenDevices() = 0;
 
@@ -277,6 +284,9 @@
 
     virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const;
 
+    virtual void vibrate(int32_t deviceId, nsecs_t duration);
+    virtual void cancelVibrate(int32_t deviceId);
+
     virtual void requestReopenDevices();
 
     virtual void wake();
@@ -303,6 +313,7 @@
         uint8_t relBitmask[(REL_MAX + 1) / 8];
         uint8_t swBitmask[(SW_MAX + 1) / 8];
         uint8_t ledBitmask[(LED_MAX + 1) / 8];
+        uint8_t ffBitmask[(FF_MAX + 1) / 8];
         uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];
 
         String8 configurationFile;
@@ -310,6 +321,9 @@
         VirtualKeyMap* virtualKeyMap;
         KeyMap keyMap;
 
+        bool ffEffectPlaying;
+        int16_t ffEffectId; // initially -1
+
         Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
         ~Device();
 
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 71eba52..8c37fbb 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -36,6 +36,9 @@
 // Log debug messages about gesture detection.
 #define DEBUG_GESTURES 0
 
+// Log debug messages about the vibrator.
+#define DEBUG_VIBRATOR 0
+
 #include "InputReader.h"
 
 #include <cutils/log.h>
@@ -273,9 +276,7 @@
             mConfigurationChangesToRefresh = 0;
             timeoutMillis = 0;
             refreshConfigurationLocked(changes);
-        }
-
-        if (timeoutMillis < 0 && mNextTimeout != LLONG_MAX) {
+        } else if (mNextTimeout != LLONG_MAX) {
             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
             timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
         }
@@ -426,6 +427,11 @@
         device->addMapper(new SwitchInputMapper(device));
     }
 
+    // Vibrator-like devices.
+    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
+        device->addMapper(new VibratorInputMapper(device));
+    }
+
     // Keyboard-like devices.
     uint32_t keyboardSource = 0;
     int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
@@ -594,6 +600,7 @@
 void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
     if (when < mNextTimeout) {
         mNextTimeout = when;
+        mEventHub->wake();
     }
 }
 
@@ -721,6 +728,27 @@
     }
 }
 
+void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+        ssize_t repeat, int32_t token) {
+    AutoMutex _l(mLock);
+
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex >= 0) {
+        InputDevice* device = mDevices.valueAt(deviceIndex);
+        device->vibrate(pattern, patternSize, repeat, token);
+    }
+}
+
+void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
+    AutoMutex _l(mLock);
+
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex >= 0) {
+        InputDevice* device = mDevices.valueAt(deviceIndex);
+        device->cancelVibrate(token);
+    }
+}
+
 void InputReader::dump(String8& dump) {
     AutoMutex _l(mLock);
 
@@ -1054,6 +1082,23 @@
     return result;
 }
 
+void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+        int32_t token) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->vibrate(pattern, patternSize, repeat, token);
+    }
+}
+
+void InputDevice::cancelVibrate(int32_t token) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->cancelVibrate(token);
+    }
+}
+
 int32_t InputDevice::getMetaState() {
     int32_t result = 0;
     size_t numMappers = mMappers.size();
@@ -1739,6 +1784,13 @@
     return false;
 }
 
+void InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+        int32_t token) {
+}
+
+void InputMapper::cancelVibrate(int32_t token) {
+}
+
 int32_t InputMapper::getMetaState() {
     return 0;
 }
@@ -1796,6 +1848,120 @@
 }
 
 
+// --- VibratorInputMapper ---
+
+VibratorInputMapper::VibratorInputMapper(InputDevice* device) :
+        InputMapper(device), mVibrating(false) {
+}
+
+VibratorInputMapper::~VibratorInputMapper() {
+}
+
+uint32_t VibratorInputMapper::getSources() {
+    return 0;
+}
+
+void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->setVibrator(true);
+}
+
+void VibratorInputMapper::process(const RawEvent* rawEvent) {
+    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
+}
+
+void VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+        int32_t token) {
+#if DEBUG_VIBRATOR
+    String8 patternStr;
+    for (size_t i = 0; i < patternSize; i++) {
+        if (i != 0) {
+            patternStr.append(", ");
+        }
+        patternStr.appendFormat("%lld", pattern[i]);
+    }
+    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
+            getDeviceId(), patternStr.string(), repeat, token);
+#endif
+
+    mVibrating = true;
+    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
+    mPatternSize = patternSize;
+    mRepeat = repeat;
+    mToken = token;
+    mIndex = -1;
+
+    nextStep();
+}
+
+void VibratorInputMapper::cancelVibrate(int32_t token) {
+#if DEBUG_VIBRATOR
+    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
+#endif
+
+    if (mVibrating && mToken == token) {
+        stopVibrating();
+    }
+}
+
+void VibratorInputMapper::timeoutExpired(nsecs_t when) {
+    if (mVibrating) {
+        if (when >= mNextStepTime) {
+            nextStep();
+        } else {
+            getContext()->requestTimeoutAtTime(mNextStepTime);
+        }
+    }
+}
+
+void VibratorInputMapper::nextStep() {
+    mIndex += 1;
+    if (size_t(mIndex) >= mPatternSize) {
+        if (mRepeat < 0) {
+            // We are done.
+            stopVibrating();
+            return;
+        }
+        mIndex = mRepeat;
+    }
+
+    bool vibratorOn = mIndex & 1;
+    nsecs_t duration = mPattern[mIndex];
+    if (vibratorOn) {
+#if DEBUG_VIBRATOR
+        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
+                getDeviceId(), duration);
+#endif
+        getEventHub()->vibrate(getDeviceId(), duration);
+    } else {
+#if DEBUG_VIBRATOR
+        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
+#endif
+        getEventHub()->cancelVibrate(getDeviceId());
+    }
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    mNextStepTime = now + duration;
+    getContext()->requestTimeoutAtTime(mNextStepTime);
+#if DEBUG_VIBRATOR
+    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
+#endif
+}
+
+void VibratorInputMapper::stopVibrating() {
+    mVibrating = false;
+#if DEBUG_VIBRATOR
+    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
+#endif
+    getEventHub()->cancelVibrate(getDeviceId());
+}
+
+void VibratorInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Vibrator Input Mapper:\n");
+    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
+}
+
+
 // --- KeyboardInputMapper ---
 
 KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index d29776d8..ed57596 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -33,6 +33,14 @@
 #include <stddef.h>
 #include <unistd.h>
 
+// Maximum supported size of a vibration pattern.
+// Must be at least 2.
+#define MAX_VIBRATE_PATTERN_SIZE 100
+
+// Maximum allowable delay value in a vibration pattern before
+// which the delay will be truncated.
+#define MAX_VIBRATE_PATTERN_DELAY_NSECS (1000000 * 1000000000LL)
+
 namespace android {
 
 class InputDevice;
@@ -267,6 +275,11 @@
      * The changes flag is a bitfield that indicates what has changed and whether
      * the input devices must all be reopened. */
     virtual void requestRefreshConfiguration(uint32_t changes) = 0;
+
+    /* Controls the vibrator of a particular input device. */
+    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+            ssize_t repeat, int32_t token) = 0;
+    virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0;
 };
 
 
@@ -334,6 +347,10 @@
 
     virtual void requestRefreshConfiguration(uint32_t changes);
 
+    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+            ssize_t repeat, int32_t token);
+    virtual void cancelVibrate(int32_t deviceId, int32_t token);
+
 protected:
     // These members are protected so they can be instrumented by test cases.
     virtual InputDevice* createDeviceLocked(int32_t deviceId,
@@ -466,6 +483,8 @@
     int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
     bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
             const int32_t* keyCodes, uint8_t* outFlags);
+    void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token);
+    void cancelVibrate(int32_t token);
 
     int32_t getMetaState();
 
@@ -848,6 +867,9 @@
     virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
     virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
             const int32_t* keyCodes, uint8_t* outFlags);
+    virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+            int32_t token);
+    virtual void cancelVibrate(int32_t token);
 
     virtual int32_t getMetaState();
 
@@ -880,6 +902,35 @@
 };
 
 
+class VibratorInputMapper : public InputMapper {
+public:
+    VibratorInputMapper(InputDevice* device);
+    virtual ~VibratorInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+            int32_t token);
+    virtual void cancelVibrate(int32_t token);
+    virtual void timeoutExpired(nsecs_t when);
+    virtual void dump(String8& dump);
+
+private:
+    bool mVibrating;
+    nsecs_t mPattern[MAX_VIBRATE_PATTERN_SIZE];
+    size_t mPatternSize;
+    ssize_t mRepeat;
+    int32_t mToken;
+    ssize_t mIndex;
+    nsecs_t mNextStepTime;
+
+    void nextStep();
+    void stopVibrating();
+};
+
+
 class KeyboardInputMapper : public InputMapper {
 public:
     KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index e59af4e..94d4189 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -646,6 +646,12 @@
         return NULL;
     }
 
+    virtual void vibrate(int32_t deviceId, nsecs_t duration) {
+    }
+
+    virtual void cancelVibrate(int32_t deviceId) {
+    }
+
     virtual bool isExternal(int32_t deviceId) const {
         return false;
     }
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 3db4601..b22be76 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -100,7 +100,7 @@
     private int mDisabledNotifications;
 
     private NotificationRecord mVibrateNotification;
-    private Vibrator mVibrator = new Vibrator();
+    private Vibrator mVibrator;
 
     // for enabling and disabling notification pulse behavior
     private boolean mScreenOn = true;
@@ -398,6 +398,7 @@
     {
         super();
         mContext = context;
+        mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mAm = ActivityManagerNative.getDefault();
         mSound = new NotificationPlayer(TAG);
         mSound.setUsesWakeLock(context);
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index ce7671f..e819432 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -105,6 +105,12 @@
             mTempInputDevicesChangedListenersToNotify =
                     new ArrayList<InputDevicesChangedListenerRecord>(); // handler thread only
 
+    // State for vibrator tokens.
+    private Object mVibratorLock = new Object();
+    private HashMap<IBinder, VibratorToken> mVibratorTokens =
+            new HashMap<IBinder, VibratorToken>();
+    private int mNextVibratorTokenValue;
+
     // State for the currently installed input filter.
     final Object mInputFilterLock = new Object();
     InputFilter mInputFilter; // guarded by mInputFilterLock
@@ -142,6 +148,9 @@
             InputChannel fromChannel, InputChannel toChannel);
     private static native void nativeSetPointerSpeed(int ptr, int speed);
     private static native void nativeSetShowTouches(int ptr, boolean enabled);
+    private static native void nativeVibrate(int ptr, int deviceId, long[] pattern,
+            int repeat, int token);
+    private static native void nativeCancelVibrate(int ptr, int deviceId, int token);
     private static native String nativeDump(int ptr);
     private static native void nativeMonitor(int ptr);
 
@@ -792,6 +801,65 @@
         return result;
     }
 
+    // Binder call
+    @Override
+    public void vibrate(int deviceId, long[] pattern, int repeat, IBinder token) {
+        if (repeat >= pattern.length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        VibratorToken v;
+        synchronized (mVibratorLock) {
+            v = mVibratorTokens.get(token);
+            if (v == null) {
+                v = new VibratorToken(deviceId, token, mNextVibratorTokenValue++);
+                try {
+                    token.linkToDeath(v, 0);
+                } catch (RemoteException ex) {
+                    // give up
+                    throw new RuntimeException(ex);
+                }
+                mVibratorTokens.put(token, v);
+            }
+        }
+
+        synchronized (v) {
+            v.mVibrating = true;
+            nativeVibrate(mPtr, deviceId, pattern, repeat, v.mTokenValue);
+        }
+    }
+
+    // Binder call
+    @Override
+    public void cancelVibrate(int deviceId, IBinder token) {
+        VibratorToken v;
+        synchronized (mVibratorLock) {
+            v = mVibratorTokens.get(token);
+            if (v == null || v.mDeviceId != deviceId) {
+                return; // nothing to cancel
+            }
+        }
+
+        cancelVibrateIfNeeded(v);
+    }
+
+    void onVibratorTokenDied(VibratorToken v) {
+        synchronized (mVibratorLock) {
+            mVibratorTokens.remove(v.mToken);
+        }
+
+        cancelVibrateIfNeeded(v);
+    }
+
+    private void cancelVibrateIfNeeded(VibratorToken v) {
+        synchronized (v) {
+            if (v.mVibrating) {
+                nativeCancelVibrate(mPtr, v.mDeviceId, v.mTokenValue);
+                v.mVibrating = false;
+            }
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -1108,4 +1176,26 @@
             }
         }
     }
+
+    private final class VibratorToken implements DeathRecipient {
+        public final int mDeviceId;
+        public final IBinder mToken;
+        public final int mTokenValue;
+
+        public boolean mVibrating;
+
+        public VibratorToken(int deviceId, IBinder token, int tokenValue) {
+            mDeviceId = deviceId;
+            mToken = token;
+            mTokenValue = tokenValue;
+        }
+
+        @Override
+        public void binderDied() {
+            if (DEBUG) {
+                Slog.d(TAG, "Vibrator token died.");
+            }
+            onVibratorTokenDied(this);
+        }
+    }
 }
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index f1536fd..3795074 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -1226,6 +1226,38 @@
     im->setShowTouches(enabled);
 }
 
+static void nativeVibrate(JNIEnv* env,
+        jclass clazz, jint ptr, jint deviceId, jlongArray patternObj,
+        jint repeat, jint token) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    size_t patternSize = env->GetArrayLength(patternObj);
+    if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
+        ALOGI("Skipped requested vibration because the pattern size is %d "
+                "which is more than the maximum supported size of %d.",
+                patternSize, MAX_VIBRATE_PATTERN_SIZE);
+        return; // limit to reasonable size
+    }
+
+    jlong* patternMillis = static_cast<jlong*>(env->GetPrimitiveArrayCritical(
+            patternObj, NULL));
+    nsecs_t pattern[patternSize];
+    for (size_t i = 0; i < patternSize; i++) {
+        pattern[i] = max(jlong(0), min(patternMillis[i],
+                MAX_VIBRATE_PATTERN_DELAY_NSECS / 1000000LL)) * 1000000LL;
+    }
+    env->ReleasePrimitiveArrayCritical(patternObj, patternMillis, JNI_ABORT);
+
+    im->getInputManager()->getReader()->vibrate(deviceId, pattern, patternSize, repeat, token);
+}
+
+static void nativeCancelVibrate(JNIEnv* env,
+        jclass clazz, jint ptr, jint deviceId, jint token) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    im->getInputManager()->getReader()->cancelVibrate(deviceId, token);
+}
+
 static jstring nativeDump(JNIEnv* env, jclass clazz, jint ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
@@ -1287,6 +1319,10 @@
             (void*) nativeSetPointerSpeed },
     { "nativeSetShowTouches", "(IZ)V",
             (void*) nativeSetShowTouches },
+    { "nativeVibrate", "(II[JII)V",
+            (void*) nativeVibrate },
+    { "nativeCancelVibrate", "(III)V",
+            (void*) nativeCancelVibrate },
     { "nativeDump", "(I)Ljava/lang/String;",
             (void*) nativeDump },
     { "nativeMonitor", "(I)V",
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 486a924..a124c7f 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -35,6 +35,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.HashMap;
 import java.util.List;
 
@@ -208,6 +209,27 @@
     protected static final int EVENT_RIL_CONNECTED = BASE + 5;
     protected static final int EVENT_DISCONNECT_ALL = BASE + 6;
 
+    private static final int CMD_TO_STRING_COUNT = EVENT_DISCONNECT_ALL + 1;
+    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
+    static {
+        sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
+        sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
+                "EVENT_SETUP_DATA_CONNECTION_DONE";
+        sCmdToString[EVENT_GET_LAST_FAIL_DONE - BASE] = "EVENT_GET_LAST_FAIL_DONE";
+        sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
+        sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
+        sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED";
+        sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL";
+    }
+    protected static String cmdToString(int cmd) {
+        cmd -= BASE;
+        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
+            return sCmdToString[cmd];
+        } else {
+            return null;
+        }
+    }
+
     //***** Tag IDs for EventLog
     protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
 
@@ -242,6 +264,7 @@
     protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
             DataConnectionTracker dct) {
         super(name);
+        setProcessedMessagesSize(100);
         if (DBG) log("DataConnection constructor E");
         this.phone = phone;
         this.mDataConnectionTracker = dct;
@@ -1188,26 +1211,65 @@
                 new DisconnectParams(reason, onCompletedMsg)));
     }
 
+    /**
+     * @return the string for msg.what as our info.
+     */
+    @Override
+    protected String getMessageInfo(Message msg) {
+        String info = null;
+        info = cmdToString(msg.what);
+        if (info == null) {
+            info = DataConnectionAc.cmdToString(msg.what);
+        }
+        return info;
+    }
+
+    /**
+     * Convert a System.currentTimeMillis() value to a time of day value.
+     *
+     * @param millis since the epoch (1/1/1970)
+     * @return String representation of the time.
+     */
+    private String timeMillisToTimeOfDay(long millis) {
+        Calendar c = Calendar.getInstance();
+        if (millis >= 0) {
+            c.setTimeInMillis(millis);
+            return String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c);
+        } else {
+            return Long.toString(millis);
+        }
+    }
+    /**
+     * Dump the current state.
+     *
+     * @param fd
+     * @param pw
+     * @param args
+     */
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("DataConnection name=" + getName() + ":");
+        pw.print("DataConnection ");
+        super.dump(fd, pw, args);
         pw.println(" mApnList=" + mApnList);
+        pw.flush();
         pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
         pw.println(" mApn=" + mApn);
         pw.println(" mTag=" + mTag);
+        pw.flush();
         pw.println(" phone=" + phone);
         pw.println(" mRilVersion=" + mRilVersion);
         pw.println(" cid=" + cid);
+        pw.flush();
         pw.println(" mLinkProperties=" + mLinkProperties);
+        pw.flush();
         pw.println(" mCapabilities=" + mCapabilities);
-        pw.println(" createTime=" + createTime);
-        pw.println(" lastFailTime=" + lastFailTime);
+        pw.println(" createTime=" + timeMillisToTimeOfDay(createTime));
+        pw.println(" lastFailTime=" + timeMillisToTimeOfDay(lastFailTime));
         pw.println(" lastFailCause=" + lastFailCause);
+        pw.flush();
         pw.println(" mRetryOverride=" + mRetryOverride);
         pw.println(" mRefCount=" + mRefCount);
         pw.println(" userData=" + userData);
-        pw.println(" total messages=" + getProcessedMessagesCount());
-        for (int i=0; i < getProcessedMessagesSize(); i++) {
-            pw.printf("  msg[%d]=%s\n", i, getProcessedMessageInfo(i));
-        }
+        pw.flush();
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
index a9f2cd1..4744ff0 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
@@ -82,6 +82,51 @@
     public static final int REQ_GET_RECONNECT_INTENT = BASE + 26;
     public static final int RSP_GET_RECONNECT_INTENT = BASE + 27;
 
+    private static final int CMD_TO_STRING_COUNT = RSP_GET_RECONNECT_INTENT + 1;
+    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
+    static {
+        sCmdToString[REQ_IS_INACTIVE - BASE] = "REQ_IS_INACTIVE";
+        sCmdToString[RSP_IS_INACTIVE - BASE] = "RSP_IS_INACTIVE";
+        sCmdToString[REQ_GET_CID - BASE] = "REQ_GET_CID";
+        sCmdToString[RSP_GET_CID - BASE] = "RSP_GET_CID";
+        sCmdToString[REQ_GET_APNSETTING - BASE] = "REQ_GET_APNSETTING";
+        sCmdToString[RSP_GET_APNSETTING - BASE] = "RSP_GET_APNSETTING";
+        sCmdToString[REQ_GET_LINK_PROPERTIES - BASE] = "REQ_GET_LINK_PROPERTIES";
+        sCmdToString[RSP_GET_LINK_PROPERTIES - BASE] = "RSP_GET_LINK_PROPERTIES";
+        sCmdToString[REQ_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] =
+                "REQ_SET_LINK_PROPERTIES_HTTP_PROXY";
+        sCmdToString[RSP_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] =
+                "RSP_SET_LINK_PROPERTIES_HTTP_PROXY";
+        sCmdToString[REQ_GET_LINK_CAPABILITIES - BASE] = "REQ_GET_LINK_CAPABILITIES";
+        sCmdToString[RSP_GET_LINK_CAPABILITIES - BASE] = "RSP_GET_LINK_CAPABILITIES";
+        sCmdToString[REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] =
+                "REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE";
+        sCmdToString[RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] =
+                "RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE";
+        sCmdToString[REQ_RESET - BASE] = "REQ_RESET";
+        sCmdToString[RSP_RESET - BASE] = "RSP_RESET";
+        sCmdToString[REQ_GET_REFCOUNT - BASE] = "REQ_GET_REFCOUNT";
+        sCmdToString[RSP_GET_REFCOUNT - BASE] = "RSP_GET_REFCOUNT";
+        sCmdToString[REQ_ADD_APNCONTEXT - BASE] = "REQ_ADD_APNCONTEXT";
+        sCmdToString[RSP_ADD_APNCONTEXT - BASE] = "RSP_ADD_APNCONTEXT";
+        sCmdToString[REQ_REMOVE_APNCONTEXT - BASE] = "REQ_REMOVE_APNCONTEXT";
+        sCmdToString[RSP_REMOVE_APNCONTEXT - BASE] = "RSP_REMOVE_APNCONTEXT";
+        sCmdToString[REQ_GET_APNCONTEXT_LIST - BASE] = "REQ_GET_APNCONTEXT_LIST";
+        sCmdToString[RSP_GET_APNCONTEXT_LIST - BASE] = "RSP_GET_APNCONTEXT_LIST";
+        sCmdToString[REQ_SET_RECONNECT_INTENT - BASE] = "REQ_SET_RECONNECT_INTENT";
+        sCmdToString[RSP_SET_RECONNECT_INTENT - BASE] = "RSP_SET_RECONNECT_INTENT";
+        sCmdToString[REQ_GET_RECONNECT_INTENT - BASE] = "REQ_GET_RECONNECT_INTENT";
+        sCmdToString[RSP_GET_RECONNECT_INTENT - BASE] = "RSP_GET_RECONNECT_INTENT";
+    }
+    protected static String cmdToString(int cmd) {
+        cmd -= BASE;
+        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
+            return sCmdToString[cmd];
+        } else {
+            return AsyncChannel.cmdToString(cmd + BASE);
+        }
+    }
+
     /**
      * enum used to notify action taken or necessary to be
      * taken after the link property is changed.
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index ae01c75..5eac1f2 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -44,7 +44,7 @@
     private final static String TAG = "NotificationTestList";
 
     NotificationManager mNM;
-    Vibrator mVibrator = new Vibrator();
+    Vibrator mVibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
     Handler mHandler = new Handler();
 
     long mActivityCreateTime = System.currentTimeMillis();