Merge "Enterprise quick contact 1/2"
diff --git a/api/current.txt b/api/current.txt
index 11a5083..97d52b5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26924,6 +26924,10 @@
     method public static android.renderscript.Element A_8(android.renderscript.RenderScript);
     method public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
     method public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16_4(android.renderscript.RenderScript);
     method public static android.renderscript.Element F32(android.renderscript.RenderScript);
     method public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
     method public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
@@ -27022,6 +27026,7 @@
     method public static android.renderscript.Element.DataType valueOf(java.lang.String);
     method public static final android.renderscript.Element.DataType[] values();
     enum_constant public static final android.renderscript.Element.DataType BOOLEAN;
+    enum_constant public static final android.renderscript.Element.DataType FLOAT_16;
     enum_constant public static final android.renderscript.Element.DataType FLOAT_32;
     enum_constant public static final android.renderscript.Element.DataType FLOAT_64;
     enum_constant public static final android.renderscript.Element.DataType MATRIX_2X2;
@@ -27295,11 +27300,14 @@
     method public static android.renderscript.RenderScript create(android.content.Context);
     method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
     method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
+    method public static android.renderscript.RenderScript createMultiContext(android.content.Context, android.renderscript.RenderScript.ContextType, int, int);
     method public void destroy();
     method public void finish();
     method public final android.content.Context getApplicationContext();
     method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
     method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
+    method public static long getMinorID();
+    method public static void releaseAllContexts();
     method public void sendMessage(int, int[]);
     method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
     method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
@@ -27381,9 +27389,12 @@
   public class Script extends android.renderscript.BaseObj {
     method public void bindAllocation(android.renderscript.Allocation, int);
     method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+    method protected android.renderscript.Script.InvokeID createInvokeID(int);
     method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
+    method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker);
+    method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
     method public boolean getVarB(int);
     method public double getVarD(int);
     method public float getVarF(int);
@@ -27421,6 +27432,9 @@
   public static final class Script.FieldID extends android.renderscript.BaseObj {
   }
 
+  public static final class Script.InvokeID extends android.renderscript.BaseObj {
+  }
+
   public static final class Script.KernelID extends android.renderscript.BaseObj {
   }
 
@@ -27631,6 +27645,8 @@
     method public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
     method public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
     method public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
+    method public int getArray(int);
+    method public int getArrayCount();
     method public int getCount();
     method public android.renderscript.Element getElement();
     method public int getX();
@@ -27644,6 +27660,7 @@
   public static class Type.Builder {
     ctor public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
     method public android.renderscript.Type create();
+    method public android.renderscript.Type.Builder setArray(int, int);
     method public android.renderscript.Type.Builder setFaces(boolean);
     method public android.renderscript.Type.Builder setMipmaps(boolean);
     method public android.renderscript.Type.Builder setX(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 874307d..831e1e6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -27888,6 +27888,108 @@
     field public static final java.lang.String SIZE = "_size";
   }
 
+  public abstract class SearchIndexableData {
+    ctor public SearchIndexableData();
+    ctor public SearchIndexableData(android.content.Context);
+    field public java.lang.String className;
+    field public android.content.Context context;
+    field public boolean enabled;
+    field public int iconResId;
+    field public java.lang.String intentAction;
+    field public java.lang.String intentTargetClass;
+    field public java.lang.String intentTargetPackage;
+    field public java.lang.String key;
+    field public java.util.Locale locale;
+    field public java.lang.String packageName;
+    field public int rank;
+    field public int userId;
+  }
+
+  public class SearchIndexableResource extends android.provider.SearchIndexableData {
+    ctor public SearchIndexableResource(int, int, java.lang.String, int);
+    ctor public SearchIndexableResource(android.content.Context);
+    field public int xmlResId;
+  }
+
+  public class SearchIndexablesContract {
+    ctor public SearchIndexablesContract();
+    field public static final int COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE = 0; // 0x0
+    field public static final int COLUMN_INDEX_RAW_CLASS_NAME = 7; // 0x7
+    field public static final int COLUMN_INDEX_RAW_ENTRIES = 4; // 0x4
+    field public static final int COLUMN_INDEX_RAW_ICON_RESID = 8; // 0x8
+    field public static final int COLUMN_INDEX_RAW_INTENT_ACTION = 9; // 0x9
+    field public static final int COLUMN_INDEX_RAW_INTENT_TARGET_CLASS = 11; // 0xb
+    field public static final int COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE = 10; // 0xa
+    field public static final int COLUMN_INDEX_RAW_KEY = 12; // 0xc
+    field public static final int COLUMN_INDEX_RAW_KEYWORDS = 5; // 0x5
+    field public static final int COLUMN_INDEX_RAW_RANK = 0; // 0x0
+    field public static final int COLUMN_INDEX_RAW_SCREEN_TITLE = 6; // 0x6
+    field public static final int COLUMN_INDEX_RAW_SUMMARY_OFF = 3; // 0x3
+    field public static final int COLUMN_INDEX_RAW_SUMMARY_ON = 2; // 0x2
+    field public static final int COLUMN_INDEX_RAW_TITLE = 1; // 0x1
+    field public static final int COLUMN_INDEX_RAW_USER_ID = 13; // 0xd
+    field public static final int COLUMN_INDEX_XML_RES_CLASS_NAME = 2; // 0x2
+    field public static final int COLUMN_INDEX_XML_RES_ICON_RESID = 3; // 0x3
+    field public static final int COLUMN_INDEX_XML_RES_INTENT_ACTION = 4; // 0x4
+    field public static final int COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS = 6; // 0x6
+    field public static final int COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE = 5; // 0x5
+    field public static final int COLUMN_INDEX_XML_RES_RANK = 0; // 0x0
+    field public static final int COLUMN_INDEX_XML_RES_RESID = 1; // 0x1
+    field public static final java.lang.String INDEXABLES_RAW = "indexables_raw";
+    field public static final java.lang.String[] INDEXABLES_RAW_COLUMNS;
+    field public static final java.lang.String INDEXABLES_RAW_PATH = "settings/indexables_raw";
+    field public static final java.lang.String INDEXABLES_XML_RES = "indexables_xml_res";
+    field public static final java.lang.String[] INDEXABLES_XML_RES_COLUMNS;
+    field public static final java.lang.String INDEXABLES_XML_RES_PATH = "settings/indexables_xml_res";
+    field public static final java.lang.String NON_INDEXABLES_KEYS = "non_indexables_key";
+    field public static final java.lang.String[] NON_INDEXABLES_KEYS_COLUMNS;
+    field public static final java.lang.String NON_INDEXABLES_KEYS_PATH = "settings/non_indexables_key";
+    field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.SEARCH_INDEXABLES_PROVIDER";
+  }
+
+  public static class SearchIndexablesContract.BaseColumns {
+    field public static final java.lang.String COLUMN_CLASS_NAME = "className";
+    field public static final java.lang.String COLUMN_ICON_RESID = "iconResId";
+    field public static final java.lang.String COLUMN_INTENT_ACTION = "intentAction";
+    field public static final java.lang.String COLUMN_INTENT_TARGET_CLASS = "intentTargetClass";
+    field public static final java.lang.String COLUMN_INTENT_TARGET_PACKAGE = "intentTargetPackage";
+    field public static final java.lang.String COLUMN_RANK = "rank";
+  }
+
+  public static final class SearchIndexablesContract.NonIndexableKey extends android.provider.SearchIndexablesContract.BaseColumns {
+    field public static final java.lang.String COLUMN_KEY_VALUE = "key";
+    field public static final java.lang.String MIME_TYPE = "vnd.android.cursor.dir/non_indexables_key";
+  }
+
+  public static final class SearchIndexablesContract.RawData extends android.provider.SearchIndexablesContract.BaseColumns {
+    field public static final java.lang.String COLUMN_ENTRIES = "entries";
+    field public static final java.lang.String COLUMN_KEY = "key";
+    field public static final java.lang.String COLUMN_KEYWORDS = "keywords";
+    field public static final java.lang.String COLUMN_SCREEN_TITLE = "screenTitle";
+    field public static final java.lang.String COLUMN_SUMMARY_OFF = "summaryOff";
+    field public static final java.lang.String COLUMN_SUMMARY_ON = "summaryOn";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_USER_ID = "user_id";
+    field public static final java.lang.String MIME_TYPE = "vnd.android.cursor.dir/indexables_raw";
+  }
+
+  public static final class SearchIndexablesContract.XmlResource extends android.provider.SearchIndexablesContract.BaseColumns {
+    field public static final java.lang.String COLUMN_XML_RESID = "xmlResId";
+    field public static final java.lang.String MIME_TYPE = "vnd.android.cursor.dir/indexables_xml_res";
+  }
+
+  public abstract class SearchIndexablesProvider extends android.content.ContentProvider {
+    ctor public SearchIndexablesProvider();
+    method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
+    method public java.lang.String getType(android.net.Uri);
+    method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+    method public abstract android.database.Cursor queryNonIndexableKeys(java.lang.String[]);
+    method public abstract android.database.Cursor queryRawData(java.lang.String[]);
+    method public abstract android.database.Cursor queryXmlResources(java.lang.String[]);
+    method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
+  }
+
   public class SearchRecentSuggestions {
     ctor public SearchRecentSuggestions(android.content.Context, java.lang.String, int);
     method public void clearHistory();
@@ -28798,6 +28900,10 @@
     method public static android.renderscript.Element A_8(android.renderscript.RenderScript);
     method public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
     method public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F16_4(android.renderscript.RenderScript);
     method public static android.renderscript.Element F32(android.renderscript.RenderScript);
     method public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
     method public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
@@ -28896,6 +29002,7 @@
     method public static android.renderscript.Element.DataType valueOf(java.lang.String);
     method public static final android.renderscript.Element.DataType[] values();
     enum_constant public static final android.renderscript.Element.DataType BOOLEAN;
+    enum_constant public static final android.renderscript.Element.DataType FLOAT_16;
     enum_constant public static final android.renderscript.Element.DataType FLOAT_32;
     enum_constant public static final android.renderscript.Element.DataType FLOAT_64;
     enum_constant public static final android.renderscript.Element.DataType MATRIX_2X2;
@@ -29169,11 +29276,14 @@
     method public static android.renderscript.RenderScript create(android.content.Context);
     method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
     method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
+    method public static android.renderscript.RenderScript createMultiContext(android.content.Context, android.renderscript.RenderScript.ContextType, int, int);
     method public void destroy();
     method public void finish();
     method public final android.content.Context getApplicationContext();
     method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
     method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
+    method public static long getMinorID();
+    method public static void releaseAllContexts();
     method public void sendMessage(int, int[]);
     method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
     method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
@@ -29255,9 +29365,12 @@
   public class Script extends android.renderscript.BaseObj {
     method public void bindAllocation(android.renderscript.Allocation, int);
     method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+    method protected android.renderscript.Script.InvokeID createInvokeID(int);
     method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
+    method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker);
+    method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
     method public boolean getVarB(int);
     method public double getVarD(int);
     method public float getVarF(int);
@@ -29295,6 +29408,9 @@
   public static final class Script.FieldID extends android.renderscript.BaseObj {
   }
 
+  public static final class Script.InvokeID extends android.renderscript.BaseObj {
+  }
+
   public static final class Script.KernelID extends android.renderscript.BaseObj {
   }
 
@@ -29505,6 +29621,8 @@
     method public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
     method public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
     method public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
+    method public int getArray(int);
+    method public int getArrayCount();
     method public int getCount();
     method public android.renderscript.Element getElement();
     method public int getX();
@@ -29518,6 +29636,7 @@
   public static class Type.Builder {
     ctor public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
     method public android.renderscript.Type create();
+    method public android.renderscript.Type.Builder setArray(int, int);
     method public android.renderscript.Type.Builder setFaces(boolean);
     method public android.renderscript.Type.Builder setMipmaps(boolean);
     method public android.renderscript.Type.Builder setX(int);
diff --git a/core/java/android/provider/SearchIndexableData.java b/core/java/android/provider/SearchIndexableData.java
index 7b9d1ea..5e0a76d 100644
--- a/core/java/android/provider/SearchIndexableData.java
+++ b/core/java/android/provider/SearchIndexableData.java
@@ -16,6 +16,7 @@
 
 package android.provider;
 
+import android.annotation.SystemApi;
 import android.content.Context;
 
 import java.util.Locale;
@@ -27,6 +28,7 @@
  *
  * @hide
  */
+@SystemApi
 public abstract class SearchIndexableData {
 
     /**
diff --git a/core/java/android/provider/SearchIndexableResource.java b/core/java/android/provider/SearchIndexableResource.java
index c807df2..1eb1734 100644
--- a/core/java/android/provider/SearchIndexableResource.java
+++ b/core/java/android/provider/SearchIndexableResource.java
@@ -16,6 +16,7 @@
 
 package android.provider;
 
+import android.annotation.SystemApi;
 import android.content.Context;
 
 /**
@@ -31,6 +32,7 @@
  *
  * @hide
  */
+@SystemApi
 public class SearchIndexableResource extends SearchIndexableData {
 
     /**
diff --git a/core/java/android/provider/SearchIndexablesContract.java b/core/java/android/provider/SearchIndexablesContract.java
index 1b5f72a..93ac7f6 100644
--- a/core/java/android/provider/SearchIndexablesContract.java
+++ b/core/java/android/provider/SearchIndexablesContract.java
@@ -16,6 +16,7 @@
 
 package android.provider;
 
+import android.annotation.SystemApi;
 import android.content.ContentResolver;
 
 /**
@@ -23,6 +24,7 @@
  *
  * @hide
  */
+@SystemApi
 public class SearchIndexablesContract {
 
     /**
@@ -234,7 +236,7 @@
     /**
      * The base columns.
      */
-    private static class BaseColumns {
+    public static class BaseColumns {
         private BaseColumns() {
         }
 
diff --git a/core/java/android/provider/SearchIndexablesProvider.java b/core/java/android/provider/SearchIndexablesProvider.java
index 9c8f6d0..3120e54 100644
--- a/core/java/android/provider/SearchIndexablesProvider.java
+++ b/core/java/android/provider/SearchIndexablesProvider.java
@@ -16,6 +16,7 @@
 
 package android.provider;
 
+import android.annotation.SystemApi;
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.Context;
@@ -61,6 +62,7 @@
  *
  * @hide
  */
+@SystemApi
 public abstract class SearchIndexablesProvider extends ContentProvider {
     private static final String TAG = "IndexablesProvider";
 
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 1bdaef0..7d2e1ef 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -356,6 +356,8 @@
             ints[DESCENT] = desc;
             objects[0] = reflowed.getLineDirections(i);
 
+            ints[HYPHEN] = reflowed.getHyphen(i);
+
             if (mEllipsize) {
                 ints[ELLIPSIS_START] = reflowed.getEllipsisStart(i);
                 ints[ELLIPSIS_COUNT] = reflowed.getEllipsisCount(i);
@@ -631,6 +633,14 @@
         return mBottomPadding;
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public int getHyphen(int line) {
+        return mInts.getValue(line, HYPHEN);
+    }
+
     @Override
     public int getEllipsizedWidth() {
         return mEllipsizedWidth;
@@ -739,11 +749,12 @@
     private static final int TAB = START;
     private static final int TOP = 1;
     private static final int DESCENT = 2;
-    private static final int COLUMNS_NORMAL = 3;
+    private static final int HYPHEN = 3;
+    private static final int COLUMNS_NORMAL = 4;
 
-    private static final int ELLIPSIS_START = 3;
-    private static final int ELLIPSIS_COUNT = 4;
-    private static final int COLUMNS_ELLIPSIZE = 5;
+    private static final int ELLIPSIS_START = 4;
+    private static final int ELLIPSIS_COUNT = 5;
+    private static final int COLUMNS_ELLIPSIZE = 6;
 
     private static final int START_MASK = 0x1FFFFFFF;
     private static final int DIR_SHIFT  = 30;
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
new file mode 100644
index 0000000..f4dff9b
--- /dev/null
+++ b/core/java/android/text/Hyphenator.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * Hyphenator is a wrapper class for a native implementation of automatic hyphenation,
+ * in essence finding valid hyphenation opportunities in a word.
+ *
+ * @hide
+ */
+/* package */ class Hyphenator {
+    // This class has deliberately simple lifetime management (no finalizer) because in
+    // the common case a process will use a very small number of locales.
+
+    private static String TAG = "Hyphenator";
+
+    static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>();
+
+    private long mNativePtr;
+
+    private Hyphenator(long nativePtr) {
+        mNativePtr = nativePtr;
+    }
+
+    public static long get(Locale locale) {
+        synchronized (sMap) {
+            Hyphenator result = sMap.get(locale);
+            if (result == null) {
+                result = loadHyphenator(locale);
+                sMap.put(locale, result);
+            }
+            return result == null ? 0 : result.mNativePtr;
+        }
+    }
+
+    private static Hyphenator loadHyphenator(Locale locale) {
+        // TODO: find pattern dictionary (from system location) that best matches locale
+        if (Locale.US.equals(locale)) {
+            File f = new File("/data/local/tmp/hyph-en-us.pat.txt");
+            try {
+                RandomAccessFile rf = new RandomAccessFile(f, "r");
+                byte[] buf = new byte[(int)rf.length()];
+                rf.read(buf);
+                rf.close();
+                String patternData = new String(buf);
+                long nativePtr = StaticLayout.nLoadHyphenator(patternData);
+                return new Hyphenator(nativePtr);
+            } catch (IOException e) {
+                Log.e(TAG, "error loading hyphenation " + f);
+            }
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 928bf16..22abb18 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -225,17 +225,17 @@
 
         // Draw the lines, one at a time.
         // The baseline is the top of the following line minus the current line's descent.
-        for (int i = firstLine; i <= lastLine; i++) {
+        for (int lineNum = firstLine; lineNum <= lastLine; lineNum++) {
             int start = previousLineEnd;
-            previousLineEnd = getLineStart(i + 1);
-            int end = getLineVisibleEnd(i, start, previousLineEnd);
+            previousLineEnd = getLineStart(lineNum + 1);
+            int end = getLineVisibleEnd(lineNum, start, previousLineEnd);
 
             int ltop = previousLineBottom;
-            int lbottom = getLineTop(i+1);
+            int lbottom = getLineTop(lineNum + 1);
             previousLineBottom = lbottom;
-            int lbaseline = lbottom - getLineDescent(i);
+            int lbaseline = lbottom - getLineDescent(lineNum);
 
-            int dir = getParagraphDirection(i);
+            int dir = getParagraphDirection(lineNum);
             int left = 0;
             int right = mWidth;
 
@@ -254,7 +254,7 @@
                 // just collect the ones present at the start of the paragraph.
                 // If spanEnd is before the end of the paragraph, that's not
                 // our problem.
-                if (start >= spanEnd && (i == firstLine || isFirstParaLine)) {
+                if (start >= spanEnd && (lineNum == firstLine || isFirstParaLine)) {
                     spanEnd = sp.nextSpanTransition(start, textLength,
                                                     ParagraphStyle.class);
                     spans = getParagraphSpans(sp, start, spanEnd, ParagraphStyle.class);
@@ -280,7 +280,7 @@
                         int startLine = getLineForOffset(sp.getSpanStart(spans[n]));
                         // if there is more than one LeadingMarginSpan2, use
                         // the count that is greatest
-                        if (i < startLine + count) {
+                        if (lineNum < startLine + count) {
                             useFirstLineMargin = true;
                             break;
                         }
@@ -304,7 +304,7 @@
                 }
             }
 
-            boolean hasTabOrEmoji = getLineContainsTab(i);
+            boolean hasTabOrEmoji = getLineContainsTab(lineNum);
             // Can't tell if we have tabs for sure, currently
             if (hasTabOrEmoji && !tabStopsIsInitialized) {
                 if (tabStops == null) {
@@ -333,7 +333,7 @@
                     x = right;
                 }
             } else {
-                int max = (int)getLineExtent(i, tabStops, false);
+                int max = (int)getLineExtent(lineNum, tabStops, false);
                 if (align == Alignment.ALIGN_OPPOSITE) {
                     if (dir == DIR_LEFT_TO_RIGHT) {
                         x = right - max;
@@ -346,7 +346,8 @@
                 }
             }
 
-            Directions directions = getLineDirections(i);
+            paint.setHyphenEdit(getHyphen(lineNum));
+            Directions directions = getLineDirections(lineNum);
             if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTabOrEmoji) {
                 // XXX: assumes there's nothing additional to be done
                 canvas.drawText(buf, start, end, x, lbaseline, paint);
@@ -677,6 +678,15 @@
      */
     public abstract int getBottomPadding();
 
+    /**
+     * Returns the hyphen edit for a line.
+     *
+     * @hide
+     */
+    public int getHyphen(int line) {
+        return 0;
+    }
+
 
     /**
      * Returns true if the character at offset and the preceding character
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index b47418f..4174df0 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -170,7 +170,8 @@
          * Measurement and break iteration is done in native code. The protocol for using
          * the native code is as follows.
          *
-         * For each paragraph, do a nSetText of the paragraph text. Also do nSetLineWidth.
+         * For each paragraph, do a nSetupParagraph, which sets paragraph text, line width, tab
+         * stops, break strategy (and possibly other parameters in the future).
          *
          * Then, for each run within the paragraph:
          *  - setLocale (this must be done at least for the first run, optional afterwards)
@@ -187,7 +188,7 @@
 
         private void setLocale(Locale locale) {
             if (!locale.equals(mLocale)) {
-                nSetLocale(mNativePtr, locale.toLanguageTag());
+                nSetLocale(mNativePtr, locale.toLanguageTag(), Hyphenator.get(locale));
                 mLocale = locale;
             }
         }
@@ -531,7 +532,7 @@
 
             int[] breaks = lineBreaks.breaks;
             float[] lineWidths = lineBreaks.widths;
-            boolean[] flags = lineBreaks.flags;
+            int[] flags = lineBreaks.flags;
 
             // here is the offset of the starting character of the line we are currently measuring
             int here = paraStart;
@@ -617,7 +618,7 @@
                     fm.top, fm.bottom,
                     v,
                     spacingmult, spacingadd, null,
-                    null, fm, false,
+                    null, fm, 0,
                     needMultiply, measured.mLevels, measured.mDir, measured.mEasy, bufEnd,
                     includepad, trackpad, null,
                     null, bufStart, ellipsize,
@@ -629,7 +630,7 @@
                       int above, int below, int top, int bottom, int v,
                       float spacingmult, float spacingadd,
                       LineHeightSpan[] chooseHt, int[] chooseHtv,
-                      Paint.FontMetricsInt fm, boolean hasTabOrEmoji,
+                      Paint.FontMetricsInt fm, int flags,
                       boolean needMultiply, byte[] chdirs, int dir,
                       boolean easy, int bufEnd, boolean includePad,
                       boolean trackPad, char[] chs,
@@ -722,8 +723,10 @@
         lines[off + mColumns + START] = end;
         lines[off + mColumns + TOP] = v;
 
-        if (hasTabOrEmoji)
-            lines[off + TAB] |= TAB_MASK;
+        // TODO: could move TAB to share same column as HYPHEN, simplifying this code and gaining
+        // one bit for start field
+        lines[off + TAB] |= flags & TAB_MASK;
+        lines[off + HYPHEN] = flags;
 
         lines[off + DIR] |= dir << DIR_SHIFT;
         Directions linedirs = DIRS_ALL_LEFT_TO_RIGHT;
@@ -942,6 +945,14 @@
         return mBottomPadding;
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public int getHyphen(int line) {
+        return mLines[mColumns * line + HYPHEN] & 0xff;
+    }
+
     @Override
     public int getEllipsisCount(int line) {
         if (mColumns < COLUMNS_ELLIPSIZE) {
@@ -968,7 +979,10 @@
     private static native long nNewBuilder();
     private static native void nFreeBuilder(long nativePtr);
     private static native void nFinishBuilder(long nativePtr);
-    private static native void nSetLocale(long nativePtr, String locale);
+
+    /* package */ static native long nLoadHyphenator(String patternData);
+
+    private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);
 
     // Set up paragraph text and settings; done as one big method to minimize jni crossings
     private static native void nSetupParagraph(long nativePtr, char[] text, int length,
@@ -991,22 +1005,23 @@
     // to reduce the number of JNI calls in the common case where the
     // arrays do not have to be resized
     private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle,
-            int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength);
+            int[] recycleBreaks, float[] recycleWidths, int[] recycleFlags, int recycleLength);
 
     private int mLineCount;
     private int mTopPadding, mBottomPadding;
     private int mColumns;
     private int mEllipsizedWidth;
 
-    private static final int COLUMNS_NORMAL = 3;
-    private static final int COLUMNS_ELLIPSIZE = 5;
+    private static final int COLUMNS_NORMAL = 4;
+    private static final int COLUMNS_ELLIPSIZE = 6;
     private static final int START = 0;
     private static final int DIR = START;
     private static final int TAB = START;
     private static final int TOP = 1;
     private static final int DESCENT = 2;
-    private static final int ELLIPSIS_START = 3;
-    private static final int ELLIPSIS_COUNT = 4;
+    private static final int HYPHEN = 3;
+    private static final int ELLIPSIS_START = 4;
+    private static final int ELLIPSIS_COUNT = 5;
 
     private int[] mLines;
     private Directions[] mLineDirections;
@@ -1028,7 +1043,7 @@
         private static final int INITIAL_SIZE = 16;
         public int[] breaks = new int[INITIAL_SIZE];
         public float[] widths = new float[INITIAL_SIZE];
-        public boolean[] flags = new boolean[INITIAL_SIZE]; // hasTabOrEmoji
+        public int[] flags = new int[INITIAL_SIZE]; // hasTabOrEmoji
         // breaks, widths, and flags should all have the same length
     }
 
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 4725581..479242c 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -955,6 +955,10 @@
                     span.updateDrawState(wp);
                 }
 
+                // Only draw hyphen on last run in line
+                if (jnext < mLen) {
+                    wp.setHyphenEdit(0);
+                }
                 x += handleText(wp, j, jnext, i, inext, runIsRtl, c, x,
                         top, y, bottom, fmi, needWidth || jnext < measureLimit);
             }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index b5e9a0b..f9729a2 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -16,18 +16,6 @@
 
 package android.widget;
 
-import android.content.UndoManager;
-import android.content.UndoOperation;
-import android.content.UndoOwner;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.InputFilter;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.GrowingArrayUtils;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.widget.EditableInputConnection;
-
 import android.R;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -35,6 +23,9 @@
 import android.content.ClipData.Item;
 import android.content.Context;
 import android.content.Intent;
+import android.content.UndoManager;
+import android.content.UndoOperation;
+import android.content.UndoOwner;
 import android.content.pm.PackageManager;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -46,13 +37,17 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.inputmethodservice.ExtractEditText;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.ParcelableParcel;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.DynamicLayout;
 import android.text.Editable;
+import android.text.InputFilter;
 import android.text.InputType;
 import android.text.Layout;
 import android.text.ParcelableSpan;
@@ -105,6 +100,11 @@
 import android.widget.TextView.Drawables;
 import android.widget.TextView.OnEditorActionListener;
 
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.widget.EditableInputConnection;
+
 import java.text.BreakIterator;
 import java.util.Arrays;
 import java.util.Comparator;
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 6cc1f68..c020020 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -21,6 +21,7 @@
 #include "unicode/brkiter.h"
 #include "utils/misc.h"
 #include "utils/Log.h"
+#include "ScopedStringChars.h"
 #include "ScopedPrimitiveArray.h"
 #include "JNIHelp.h"
 #include "core_jni_helpers.h"
@@ -71,14 +72,14 @@
 }
 
 static void recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks,
-                        jfloatArray recycleWidths, jbooleanArray recycleFlags,
+                        jfloatArray recycleWidths, jintArray recycleFlags,
                         jint recycleLength, size_t nBreaks, const jint* breaks,
-                        const jfloat* widths, const jboolean* flags) {
+                        const jfloat* widths, const jint* flags) {
     if ((size_t)recycleLength < nBreaks) {
         // have to reallocate buffers
         recycleBreaks = env->NewIntArray(nBreaks);
         recycleWidths = env->NewFloatArray(nBreaks);
-        recycleFlags = env->NewBooleanArray(nBreaks);
+        recycleFlags = env->NewIntArray(nBreaks);
 
         env->SetObjectField(recycle, gLineBreaks_fieldID.breaks, recycleBreaks);
         env->SetObjectField(recycle, gLineBreaks_fieldID.widths, recycleWidths);
@@ -87,12 +88,12 @@
     // copy data
     env->SetIntArrayRegion(recycleBreaks, 0, nBreaks, breaks);
     env->SetFloatArrayRegion(recycleWidths, 0, nBreaks, widths);
-    env->SetBooleanArrayRegion(recycleFlags, 0, nBreaks, flags);
+    env->SetIntArrayRegion(recycleFlags, 0, nBreaks, flags);
 }
 
 static jint nComputeLineBreaks(JNIEnv* env, jclass, jlong nativePtr,
                                jobject recycle, jintArray recycleBreaks,
-                               jfloatArray recycleWidths, jbooleanArray recycleFlags,
+                               jfloatArray recycleWidths, jintArray recycleFlags,
                                jint recycleLength) {
     LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
 
@@ -119,12 +120,20 @@
     b->finish();
 }
 
-static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleName) {
+static jlong nLoadHyphenator(JNIEnv* env, jclass, jstring patternData) {
+    ScopedStringChars str(env, patternData);
+    Hyphenator* hyphenator = Hyphenator::load(str.get(), str.size());
+    return reinterpret_cast<jlong>(hyphenator);
+}
+
+static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleName,
+        jlong nativeHyphenator) {
     ScopedIcuLocale icuLocale(env, javaLocaleName);
     LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
+    Hyphenator* hyphenator = reinterpret_cast<Hyphenator*>(nativeHyphenator);
 
     if (icuLocale.valid()) {
-        b->setLocale(icuLocale.locale());
+        b->setLocale(icuLocale.locale(), hyphenator);
     }
 }
 
@@ -164,13 +173,14 @@
     {"nNewBuilder", "()J", (void*) nNewBuilder},
     {"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
     {"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
-    {"nSetLocale", "(JLjava/lang/String;)V", (void*) nSetLocale},
+    {"nLoadHyphenator", "(Ljava/lang/String;)J", (void*) nLoadHyphenator},
+    {"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
     {"nSetupParagraph", "(J[CIFIF[III)V", (void*) nSetupParagraph},
     {"nAddStyleRun", "(JJJIIZ)F", (void*) nAddStyleRun},
     {"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun},
     {"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun},
     {"nGetWidths", "(J[F)V", (void*) nGetWidths},
-    {"nComputeLineBreaks", "(JLandroid/text/StaticLayout$LineBreaks;[I[F[ZI)I",
+    {"nComputeLineBreaks", "(JLandroid/text/StaticLayout$LineBreaks;[I[F[II)I",
         (void*) nComputeLineBreaks}
 };
 
@@ -181,7 +191,7 @@
 
     gLineBreaks_fieldID.breaks = GetFieldIDOrDie(env, gLineBreaks_class, "breaks", "[I");
     gLineBreaks_fieldID.widths = GetFieldIDOrDie(env, gLineBreaks_class, "widths", "[F");
-    gLineBreaks_fieldID.flags = GetFieldIDOrDie(env, gLineBreaks_class, "flags", "[Z");
+    gLineBreaks_fieldID.flags = GetFieldIDOrDie(env, gLineBreaks_class, "flags", "[I");
 
     return RegisterMethodsOrDie(env, "android/text/StaticLayout", gMethods, NELEM(gMethods));
 }
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index b08fbcf..e8706c1 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -78,6 +78,19 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>Build Tools, Revision 22.0.1</a> <em>(March 2015)</em>
+  </p>
+  <div class="toggle-content-toggleme">
+    <p>Fixed compatibility issues with
+    <a href="{@docRoot}guide/topics/renderscript/compute.html">RenderScript</a> kernels on
+    Android 4.4 (API level 19) to Android 4.1 (API level 16) devices.</p>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>Build Tools, Revision 22.0.0</a> <em>(March 2015)</em>
   </p>
   <div class="toggle-content-toggleme">
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3781969..02fbd89 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -858,6 +858,8 @@
                 .setModelViewMapUnitToRectOptionalSnap(snap, rect)
                 .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                 .build();
+        renderGlop(glop);
+        return;
     }
 
     float alpha = getLayerAlpha(layer);
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
index 3627e3e..7d5bf6b 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -36,7 +36,10 @@
  * allows the user to return to the call.
  */
 public class EmergencyButton extends Button {
-    private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
+    private static final Intent INTENT_EMERGENCY_DIAL = new Intent()
+            .setAction("com.android.phone.EmergencyDialer.DIAL")
+            .setPackage("com.android.phone")
+            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
 
     KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -112,12 +115,9 @@
                 mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
             }
         } else {
-            final boolean bypassHandler = true;
-            KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(bypassHandler);
-            Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            getContext().startActivityAsUser(intent,
+            KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(
+                    true /* bypassHandler */);
+            getContext().startActivityAsUser(INTENT_EMERGENCY_DIAL,
                     new UserHandle(mLockPatternUtils.getCurrentUser()));
         }
     }
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 60ff996..4b3e30f 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -119,9 +119,6 @@
      */
     public enum DataType {
         NONE (0, 0),
-        /**
-         *     @hide
-         */
         FLOAT_16 (1, 2),
         FLOAT_32 (2, 4),
         FLOAT_64 (3, 8),
@@ -390,9 +387,6 @@
         return rs.mElement_I64;
     }
 
-    /**
-     *     @hide
-     */
     public static Element F16(RenderScript rs) {
         if(rs.mElement_F16 == null) {
             rs.mElement_F16 = createUser(rs, DataType.FLOAT_16);
@@ -534,9 +528,6 @@
         return rs.mElement_RGBA_8888;
     }
 
-    /**
-     *     @hide
-     */
     public static Element F16_2(RenderScript rs) {
         if(rs.mElement_HALF_2 == null) {
             rs.mElement_HALF_2 = createVector(rs, DataType.FLOAT_16, 2);
@@ -544,9 +535,6 @@
         return rs.mElement_HALF_2;
     }
 
-    /**
-     *     @hide
-     */
     public static Element F16_3(RenderScript rs) {
         if(rs.mElement_FLOAT_3 == null) {
             rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_16, 3);
@@ -554,9 +542,6 @@
         return rs.mElement_HALF_3;
     }
 
-    /**
-     *     @hide
-     */
     public static Element F16_4(RenderScript rs) {
         if(rs.mElement_HALF_4 == null) {
             rs.mElement_HALF_4 = createVector(rs, DataType.FLOAT_16, 4);
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index e8e942c..7ef17a7 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -139,7 +139,8 @@
      * Returns an identifier that can be used to identify a particular
      * minor version of RS.
      *
-     * @hide
+     * @return The minor RenderScript version number
+     *
      */
     public static long getMinorID() {
         return sMinorID;
@@ -1321,7 +1322,6 @@
     /**
      * Create a RenderScript context.
      *
-     * @hide
      * @param ctx The context.
      * @return RenderScript
      */
@@ -1418,14 +1418,13 @@
      /**
      * Gets or creates a RenderScript context of the specified type.
      *
-     * @hide
      * @param ctx The context.
      * @param ct The type of context to be created.
      * @param sdkVersion The target SDK Version.
      * @param flags The OR of the CREATE_FLAG_* options desired
      * @return RenderScript
      */
-    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
+    private static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
         if (sdkVersion < 23) {
             return internalCreate(ctx, sdkVersion, ct, flags);
         }
@@ -1448,8 +1447,6 @@
     }
 
     /**
-     * @hide
-     *
      * Releases all the process contexts.  This is the same as
      * calling .destroy() on each unique context retreived with
      * create(...). If no contexts have been created this
@@ -1486,7 +1483,6 @@
      *
      * If you need a single context please use create()
      *
-     * @hide
      * @param ctx The context.
      * @return RenderScript
      */
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index 65056ac..44a8a27 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -66,7 +66,6 @@
     }
 
     /**
-     * @hide Pending API review
      * InvokeID is an identifier for an invoke function. It is used
      * as an identifier for ScriptGroup creation.
      *
@@ -86,7 +85,6 @@
 
     private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
     /**
-     * @hide Pending API review
      * Only to be used by generated reflected classes.
      */
     protected InvokeID createInvokeID(int slot) {
@@ -222,22 +220,21 @@
 
     /**
      * Only intended for use by generated reflected code.
-     *
-     * @hide
      */
     protected void forEach(int slot, Allocation[] ains, Allocation aout,
                            FieldPacker v) {
+
+        // FieldPacker is kept here to support regular params in the future.
         forEach(slot, ains, aout, v, null);
     }
 
     /**
      * Only intended for use by generated reflected code.
-     *
-     * @hide
      */
     protected void forEach(int slot, Allocation[] ains, Allocation aout,
                            FieldPacker v, LaunchOptions sc) {
         // TODO: Is this necessary if nScriptForEach calls validate as well?
+        // FieldPacker is kept here to support regular params in the future.
         mRS.validate();
         if (ains != null) {
             for (Allocation ain : ains) {
diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java
index a58e42c..cc9b58b 100644
--- a/rs/java/android/renderscript/Type.java
+++ b/rs/java/android/renderscript/Type.java
@@ -150,24 +150,29 @@
     }
 
     /**
-     * @hide
-     */
-    public int getArray(int dim) {
-        if ((dim < 0) || (dim >= mMaxArrays)) {
+      * Return the dimension of the specified array.
+      *
+      * @param arrayNum  The array dimension to query
+      * @return int
+      */
+    public int getArray(int arrayNum) {
+        if ((arrayNum < 0) || (arrayNum >= mMaxArrays)) {
             throw new RSIllegalArgumentException("Array dimension out of range.");
         }
 
-        if (mArrays == null || dim >= mArrays.length) {
+        if (mArrays == null || arrayNum >= mArrays.length) {
             // Dimension in range but no array for that dimension allocated
             return 0;
         }
 
-        return mArrays[dim];
+        return mArrays[arrayNum];
     }
 
     /**
-     * @hide
-     */
+      * Return the number of array dimensions.
+      *
+      * @return int
+      */
     public int getArrayCount() {
         if (mArrays != null) return mArrays.length;
         return 0;
@@ -377,7 +382,7 @@
         }
 
         /**
-         * @hide
+         * Adds an array dimension to the builder
          *
          * @param dim
          * @param value
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index be6550c..87cf06e 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1398,6 +1398,14 @@
                     public void onDebug() {
                         // no-op
                     }
+                    @Override
+                    public void onDown() {
+                        mOrientationListener.onTouchStart();
+                    }
+                    @Override
+                    public void onUpOrCancel() {
+                        mOrientationListener.onTouchEnd();
+                    }
                 });
         mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
         mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
index cfa631f..627b328 100644
--- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
@@ -75,6 +75,7 @@
                 mDebugFireable = true;
                 mDownPointers = 0;
                 captureDown(event, 0);
+                mCallbacks.onDown();
                 break;
             case MotionEvent.ACTION_POINTER_DOWN:
                 captureDown(event, event.getActionIndex());
@@ -106,6 +107,7 @@
             case MotionEvent.ACTION_CANCEL:
                 mSwipeFireable = false;
                 mDebugFireable = false;
+                mCallbacks.onUpOrCancel();
                 break;
             default:
                 if (DEBUG) Slog.d(TAG, "Ignoring " + event);
@@ -192,6 +194,8 @@
         void onSwipeFromTop();
         void onSwipeFromBottom();
         void onSwipeFromRight();
+        void onDown();
+        void onUpOrCancel();
         void onDebug();
     }
 }
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 0118127..a33ee4c 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -22,6 +22,7 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.os.Handler;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.Log;
 import android.util.Slog;
@@ -133,6 +134,20 @@
         }
     }
 
+    public void onTouchStart() {
+        synchronized (mLock) {
+            mSensorEventListener.onTouchStartLocked();
+        }
+    }
+
+    public void onTouchEnd() {
+        long whenElapsedNanos = SystemClock.elapsedRealtimeNanos();
+
+        synchronized (mLock) {
+            mSensorEventListener.onTouchEndLocked(whenElapsedNanos);
+        }
+    }
+
     /**
      * Sets the current rotation.
      *
@@ -269,6 +284,11 @@
         private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
                 500 * NANOS_PER_MS;
 
+        // The minimum amount of time that must have elapsed since the screen was last touched
+        // before the proposed rotation can change.
+        private static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
+                500 * NANOS_PER_MS;
+
         // If the tilt angle remains greater than the specified angle for a minimum of
         // the specified time, then the device is deemed to be lying flat
         // (just chillin' on a table).
@@ -398,6 +418,10 @@
         private long mAccelerationTimestampNanos;
         private boolean mAccelerating;
 
+        // Timestamp when the last touch to the touch screen ended
+        private long mTouchEndedTimestampNanos = Long.MIN_VALUE;
+        private boolean mTouched;
+
         // Whether we are locked into an overhead usage mode.
         private boolean mOverhead;
 
@@ -422,6 +446,7 @@
             pw.println(prefix + "mSwinging=" + mSwinging);
             pw.println(prefix + "mAccelerating=" + mAccelerating);
             pw.println(prefix + "mOverhead=" + mOverhead);
+            pw.println(prefix + "mTouched=" + mTouched);
         }
 
         @Override
@@ -601,6 +626,7 @@
                             + ", isFlat=" + isFlat
                             + ", isSwinging=" + isSwinging
                             + ", isOverhead=" + mOverhead
+                            + ", isTouched=" + mTouched
                             + ", timeUntilSettledMS=" + remainingMS(now,
                                     mPredictedRotationTimestampNanos + PROPOSAL_SETTLE_TIME_NANOS)
                             + ", timeUntilAccelerationDelayExpiredMS=" + remainingMS(now,
@@ -608,7 +634,9 @@
                             + ", timeUntilFlatDelayExpiredMS=" + remainingMS(now,
                                     mFlatTimestampNanos + PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS)
                             + ", timeUntilSwingDelayExpiredMS=" + remainingMS(now,
-                                    mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS));
+                                    mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS)
+                            + ", timeUntilTouchDelayExpiredMS=" + remainingMS(now,
+                                    mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS));
                 }
             }
 
@@ -710,6 +738,12 @@
                 return false;
             }
 
+            // The last touch must have ended sufficiently long ago.
+            if (mTouched || now < mTouchEndedTimestampNanos
+                    + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS) {
+                return false;
+            }
+
             // Looks good!
             return true;
         }
@@ -796,5 +830,14 @@
         private float remainingMS(long now, long until) {
             return now >= until ? 0 : (until - now) * 0.000001f;
         }
+
+        private void onTouchStartLocked() {
+            mTouched = true;
+        }
+
+        private void onTouchEndLocked(long whenElapsedNanos) {
+            mTouched = false;
+            mTouchEndedTimestampNanos = whenElapsedNanos;
+        }
     }
 }
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
index 24e4b54..c72efc2 100644
--- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
@@ -166,7 +166,7 @@
             if (lineBreaks.breaks.length != mBreaksList.size()) {
                 lineBreaks.breaks = new int[mBreaksList.size()];
                 lineBreaks.widths = new float[mWidthsList.size()];
-                lineBreaks.flags = new boolean[mFlagsList.size()];
+                lineBreaks.flags = new int[mFlagsList.size()];
             }
 
             int i = 0;
@@ -181,7 +181,7 @@
             }
             i = 0;
             for (boolean b : mFlagsList) {
-                lineBreaks.flags[i] = b;
+                lineBreaks.flags[i] = b ? TAB_MASK : 0;
                 i++;
             }
 
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
index 8be3635..54445a4 100644
--- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
@@ -26,6 +26,8 @@
 // frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
 public abstract class LineBreaker {
 
+    protected static final int TAB_MASK   = 0x20000000;  // keep in sync with StaticLayout
+
     protected final @NonNull List<Primitive> mPrimitives;
     protected final @NonNull LineWidth mLineWidth;
     protected final @NonNull TabStops mTabStops;
diff --git a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
index d5d7798..cd92581 100644
--- a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
@@ -51,7 +51,7 @@
             assert p.type == PrimitiveType.PENALTY;
             breakInfo.breaks = new int[]{0};
             breakInfo.widths = new float[]{p.width};
-            breakInfo.flags = new boolean[]{false};
+            breakInfo.flags = new int[]{0};
             return;
         }
         Node[] opt = new Node[numBreaks];
@@ -129,7 +129,7 @@
 
             breakInfo.breaks[count] = mPrimitives.get(idx).location;
             breakInfo.widths[count] = opt[idx].mWidth;
-            breakInfo.flags [count] = opt[idx].mHasTabs;
+            breakInfo.flags [count] = opt[idx].mHasTabs ? TAB_MASK : 0;
             idx = opt[idx].mPrev;
         }
     }
@@ -140,7 +140,7 @@
         }
         int[] breaks = new int[size];
         float[] widths = new float[size];
-        boolean[] flags = new boolean[size];
+        int[] flags = new int[size];
 
         int toCopy = Math.min(size, lineBreaks.breaks.length);
         System.arraycopy(lineBreaks.breaks, 0, breaks, 0, toCopy);