Merge "Process: Fix communication with zygote." into nyc-dev
diff --git a/Android.mk b/Android.mk
index e741d9b..49825b9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1192,20 +1192,45 @@
LOCAL_DROIDDOC_OPTIONS:= \
$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
- -devsite \
- -hdf devsite true \
-toroot / \
-hdf android.whichdoc online \
+ -devsite \
$(sample_groups) \
- -useUpdatedTemplates \
-hdf android.hasSamples true \
- -yaml _book.yaml \
-samplesdir $(samples_dir)
LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk-dev
include $(BUILD_DROIDDOC)
+# ==== docs for the web (on the devsite app engine server) =======================
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
+LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_STATIC_JAVA_LIBRARIES:=$(framework_docs_LOCAL_STATIC_JAVA_LIBRARIES)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
+LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
+# specify a second html input dir and an output path relative to OUT_DIR)
+LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl /
+
+LOCAL_MODULE := ds-static
+
+LOCAL_DROIDDOC_OPTIONS:= \
+ $(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
+ -hdf android.whichdoc online \
+ -staticonly \
+ -toroot / \
+ -devsite \
+ -ignoreJdLinks
+
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk-dev
+
+include $(BUILD_DROIDDOC)
+
# ==== site updates for docs (on the androiddevdocs app engine server) =======================
include $(CLEAR_VARS)
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index ae78e218..c4eaccc 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -628,8 +628,8 @@
if (connection == null) {
return false;
}
- List<MotionEvent> events = MotionEventGenerator.getMotionEventsFromGestureDescription(
- gesture, 100);
+ List<GestureDescription.GestureStep> steps =
+ MotionEventGenerator.getGestureStepsFromGestureDescription(gesture, 100);
try {
synchronized (mLock) {
mGestureStatusCallbackSequence++;
@@ -641,8 +641,8 @@
callback, handler);
mGestureStatusCallbackInfos.put(mGestureStatusCallbackSequence, callbackInfo);
}
- connection.sendMotionEvents(mGestureStatusCallbackSequence,
- new ParceledListSlice<>(events));
+ connection.sendGesture(mGestureStatusCallbackSequence,
+ new ParceledListSlice<>(steps));
}
} catch (RemoteException re) {
throw new RuntimeException(re);
diff --git a/core/java/android/accessibilityservice/GestureDescription.java b/core/java/android/accessibilityservice/GestureDescription.java
index fc9581e..d9b03fa 100644
--- a/core/java/android/accessibilityservice/GestureDescription.java
+++ b/core/java/android/accessibilityservice/GestureDescription.java
@@ -21,6 +21,8 @@
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
@@ -303,13 +305,37 @@
}
}
- private static class TouchPoint {
+ /**
+ * The location of a finger for gesture dispatch
+ *
+ * @hide
+ */
+ public static class TouchPoint implements Parcelable {
+ private static final int FLAG_IS_START_OF_PATH = 0x01;
+ private static final int FLAG_IS_END_OF_PATH = 0x02;
+
int mPathIndex;
boolean mIsStartOfPath;
boolean mIsEndOfPath;
float mX;
float mY;
+ public TouchPoint() {
+ }
+
+ public TouchPoint(TouchPoint pointToCopy) {
+ copyFrom(pointToCopy);
+ }
+
+ public TouchPoint(Parcel parcel) {
+ mPathIndex = parcel.readInt();
+ int startEnd = parcel.readInt();
+ mIsStartOfPath = (startEnd & FLAG_IS_START_OF_PATH) != 0;
+ mIsEndOfPath = (startEnd & FLAG_IS_END_OF_PATH) != 0;
+ mX = parcel.readFloat();
+ mY = parcel.readFloat();
+ }
+
void copyFrom(TouchPoint other) {
mPathIndex = other.mPathIndex;
mIsStartOfPath = other.mIsStartOfPath;
@@ -317,12 +343,94 @@
mX = other.mX;
mY = other.mY;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mPathIndex);
+ int startEnd = mIsStartOfPath ? FLAG_IS_START_OF_PATH : 0;
+ startEnd |= mIsEndOfPath ? FLAG_IS_END_OF_PATH : 0;
+ dest.writeInt(startEnd);
+ dest.writeFloat(mX);
+ dest.writeFloat(mY);
+ }
+
+ public static final Parcelable.Creator<TouchPoint> CREATOR
+ = new Parcelable.Creator<TouchPoint>() {
+ public TouchPoint createFromParcel(Parcel in) {
+ return new TouchPoint(in);
+ }
+
+ public TouchPoint[] newArray(int size) {
+ return new TouchPoint[size];
+ }
+ };
+ }
+
+ /**
+ * A step along a gesture. Contains all of the touch points at a particular time
+ *
+ * @hide
+ */
+ public static class GestureStep implements Parcelable {
+ public long timeSinceGestureStart;
+ public int numTouchPoints;
+ public TouchPoint[] touchPoints;
+
+ public GestureStep(long timeSinceGestureStart, int numTouchPoints,
+ TouchPoint[] touchPointsToCopy) {
+ this.timeSinceGestureStart = timeSinceGestureStart;
+ this.numTouchPoints = numTouchPoints;
+ this.touchPoints = new TouchPoint[numTouchPoints];
+ for (int i = 0; i < numTouchPoints; i++) {
+ this.touchPoints[i] = new TouchPoint(touchPointsToCopy[i]);
+ }
+ }
+
+ public GestureStep(Parcel parcel) {
+ timeSinceGestureStart = parcel.readLong();
+ Parcelable[] parcelables =
+ parcel.readParcelableArray(TouchPoint.class.getClassLoader());
+ numTouchPoints = (parcelables == null) ? 0 : parcelables.length;
+ touchPoints = new TouchPoint[numTouchPoints];
+ for (int i = 0; i < numTouchPoints; i++) {
+ touchPoints[i] = (TouchPoint) parcelables[i];
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(timeSinceGestureStart);
+ dest.writeParcelableArray(touchPoints, flags);
+ }
+
+ public static final Parcelable.Creator<GestureStep> CREATOR
+ = new Parcelable.Creator<GestureStep>() {
+ public GestureStep createFromParcel(Parcel in) {
+ return new GestureStep(in);
+ }
+
+ public GestureStep[] newArray(int size) {
+ return new GestureStep[size];
+ }
+ };
}
/**
* Class to convert a GestureDescription to a series of MotionEvents.
+ *
+ * @hide
*/
- static class MotionEventGenerator {
+ public static class MotionEventGenerator {
/**
* Constants used to initialize all MotionEvents
*/
@@ -341,39 +449,53 @@
private static PointerCoords[] sPointerCoords;
private static PointerProperties[] sPointerProps;
- static List<MotionEvent> getMotionEventsFromGestureDescription(
+ static List<GestureStep> getGestureStepsFromGestureDescription(
GestureDescription description, int sampleTimeMs) {
- final List<MotionEvent> motionEvents = new ArrayList<>();
+ final List<GestureStep> gestureSteps = new ArrayList<>();
// Point data at each time we generate an event for
final TouchPoint[] currentTouchPoints =
getCurrentTouchPoints(description.getStrokeCount());
- // Point data sent in last touch event
- int lastTouchPointSize = 0;
- final TouchPoint[] lastTouchPoints =
- getLastTouchPoints(description.getStrokeCount());
-
+ int currentTouchPointSize = 0;
/* Loop through each time slice where there are touch points */
long timeSinceGestureStart = 0;
long nextKeyPointTime = description.getNextKeyPointAtLeast(timeSinceGestureStart);
while (nextKeyPointTime >= 0) {
- timeSinceGestureStart = (lastTouchPointSize == 0) ? nextKeyPointTime
+ timeSinceGestureStart = (currentTouchPointSize == 0) ? nextKeyPointTime
: Math.min(nextKeyPointTime, timeSinceGestureStart + sampleTimeMs);
- int currentTouchPointSize = description.getPointsForTime(timeSinceGestureStart,
+ currentTouchPointSize = description.getPointsForTime(timeSinceGestureStart,
currentTouchPoints);
-
- appendMoveEventIfNeeded(motionEvents, lastTouchPoints, lastTouchPointSize,
- currentTouchPoints, currentTouchPointSize, timeSinceGestureStart);
- lastTouchPointSize = appendUpEvents(motionEvents, lastTouchPoints,
- lastTouchPointSize, currentTouchPoints, currentTouchPointSize,
- timeSinceGestureStart);
- lastTouchPointSize = appendDownEvents(motionEvents, lastTouchPoints,
- lastTouchPointSize, currentTouchPoints, currentTouchPointSize,
- timeSinceGestureStart);
+ gestureSteps.add(new GestureStep(timeSinceGestureStart, currentTouchPointSize,
+ currentTouchPoints));
/* Move to next time slice */
nextKeyPointTime = description.getNextKeyPointAtLeast(timeSinceGestureStart + 1);
}
+ return gestureSteps;
+ }
+
+ public static List<MotionEvent> getMotionEventsFromGestureSteps(List<GestureStep> steps) {
+ final List<MotionEvent> motionEvents = new ArrayList<>();
+
+ // Number of points in last touch event
+ int lastTouchPointSize = 0;
+ TouchPoint[] lastTouchPoints;
+
+ for (int i = 0; i < steps.size(); i++) {
+ GestureStep step = steps.get(i);
+ int currentTouchPointSize = step.numTouchPoints;
+ lastTouchPoints = getLastTouchPoints(
+ Math.max(lastTouchPointSize, currentTouchPointSize));
+
+ appendMoveEventIfNeeded(motionEvents, lastTouchPoints, lastTouchPointSize,
+ step.touchPoints, currentTouchPointSize, step.timeSinceGestureStart);
+ lastTouchPointSize = appendUpEvents(motionEvents, lastTouchPoints,
+ lastTouchPointSize, step.touchPoints, currentTouchPointSize,
+ step.timeSinceGestureStart);
+ lastTouchPointSize = appendDownEvents(motionEvents, lastTouchPoints,
+ lastTouchPointSize, step.touchPoints, currentTouchPointSize,
+ step.timeSinceGestureStart);
+ }
return motionEvents;
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 7a55079..81cddba 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -88,5 +88,5 @@
void setSoftKeyboardCallbackEnabled(boolean enabled);
- void sendMotionEvents(int sequence, in ParceledListSlice events);
+ void sendGesture(int sequence, in ParceledListSlice gestureSteps);
}
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index e435580..633e85b 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -17,7 +17,8 @@
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about using fragments, read the
- * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * <a href="{@docRoot}guide/components/fragments.html">Fragments</a> developer
+ * guide.</p>
* </div>
*/
public abstract class FragmentTransaction {
@@ -25,17 +26,17 @@
* Calls {@link #add(int, Fragment, String)} with a 0 containerViewId.
*/
public abstract FragmentTransaction add(Fragment fragment, String tag);
-
+
/**
* Calls {@link #add(int, Fragment, String)} with a null tag.
*/
public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment);
-
+
/**
* Add a fragment to the activity state. This fragment may optionally
* also have its view (if {@link Fragment#onCreateView Fragment.onCreateView}
* returns non-null) inserted into a container view of the activity.
- *
+ *
* @param containerViewId Optional identifier of the container this fragment is
* to be placed in. If 0, it will not be placed in a container.
* @param fragment The fragment to be added. This fragment must not already
@@ -43,64 +44,64 @@
* @param tag Optional tag name for the fragment, to later retrieve the
* fragment with {@link FragmentManager#findFragmentByTag(String)
* FragmentManager.findFragmentByTag(String)}.
- *
+ *
* @return Returns the same FragmentTransaction instance.
*/
public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment,
String tag);
-
+
/**
* Calls {@link #replace(int, Fragment, String)} with a null tag.
*/
public abstract FragmentTransaction replace(@IdRes int containerViewId, Fragment fragment);
-
+
/**
* Replace an existing fragment that was added to a container. This is
* essentially the same as calling {@link #remove(Fragment)} for all
* currently added fragments that were added with the same containerViewId
* and then {@link #add(int, Fragment, String)} with the same arguments
* given here.
- *
+ *
* @param containerViewId Identifier of the container whose fragment(s) are
* to be replaced.
* @param fragment The new fragment to place in the container.
* @param tag Optional tag name for the fragment, to later retrieve the
* fragment with {@link FragmentManager#findFragmentByTag(String)
* FragmentManager.findFragmentByTag(String)}.
- *
+ *
* @return Returns the same FragmentTransaction instance.
*/
public abstract FragmentTransaction replace(@IdRes int containerViewId, Fragment fragment,
String tag);
-
+
/**
* Remove an existing fragment. If it was added to a container, its view
* is also removed from that container.
- *
+ *
* @param fragment The fragment to be removed.
- *
+ *
* @return Returns the same FragmentTransaction instance.
*/
public abstract FragmentTransaction remove(Fragment fragment);
-
+
/**
* Hides an existing fragment. This is only relevant for fragments whose
* views have been added to a container, as this will cause the view to
* be hidden.
- *
+ *
* @param fragment The fragment to be hidden.
- *
+ *
* @return Returns the same FragmentTransaction instance.
*/
public abstract FragmentTransaction hide(Fragment fragment);
-
+
/**
* Shows a previously hidden fragment. This is only relevant for fragments whose
* views have been added to a container, as this will cause the view to
* be shown.
- *
+ *
* @param fragment The fragment to be shown.
- *
+ *
* @return Returns the same FragmentTransaction instance.
*/
public abstract FragmentTransaction show(Fragment fragment);
@@ -135,17 +136,17 @@
* <code>false</code> otherwise.
*/
public abstract boolean isEmpty();
-
+
/**
* Bit mask that is set for all enter transitions.
*/
public static final int TRANSIT_ENTER_MASK = 0x1000;
-
+
/**
* Bit mask that is set for all exit transitions.
*/
public static final int TRANSIT_EXIT_MASK = 0x2000;
-
+
/** Not set up for a transition. */
public static final int TRANSIT_UNSET = -1;
/** No animation for transition. */
@@ -202,7 +203,7 @@
* animations.
*/
public abstract FragmentTransaction setTransitionStyle(@StyleRes int styleRes);
-
+
/**
* Add this transaction to the back stack. This means that the transaction
* will be remembered after it is committed, and will reverse its operation
@@ -269,7 +270,7 @@
* because the state after the commit can be lost if the activity needs to
* be restored from its state. See {@link #commitAllowingStateLoss()} for
* situations where it may be okay to lose the commit.</p>
- *
+ *
* @return Returns the identifier of this transaction's back stack entry,
* if {@link #addToBackStack(String)} had been called. Otherwise, returns
* a negative number.
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 7f9e176..4b09fed 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -72,7 +72,9 @@
* {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
- * @param value The new value for the preference.
+ * @param value The new value for the preference. Passing {@code null}
+ * for this argument is equivalent to calling {@link #remove(String)} with
+ * this key.
*
* @return Returns a reference to the same Editor object, so you can
* chain put calls together.
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 2e0dfa5..7f2f740 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -354,7 +354,7 @@
return false;
}
} catch (RemoteException re) {
- return true;
+ return false;
}
}
@@ -435,7 +435,7 @@
return false;
}
} catch (RemoteException re) {
- return true;
+ return false;
}
}
diff --git a/docs/html/guide/components/intents-common.jd b/docs/html/guide/components/intents-common.jd
index 9488f6e..e6c9fc6 100644
--- a/docs/html/guide/components/intents-common.jd
+++ b/docs/html/guide/components/intents-common.jd
@@ -99,7 +99,6 @@
</ol>
</li>
<li><a href="#AdbIntents">Verify Intents with the Android Debug Bridge</a></li>
- <li><a href="#Now">Intents Fired by Google Now</a></li>
</ol>
<h2>See also</h2>
@@ -110,9 +109,9 @@
</div>
</div>
-<!-- Google Now box styles -->
+<!-- Google Voice Actions box styles -->
<style type="text/css">
-.now-box {
+.voice-box {
border-color: rgb(204,204,204);
border-style: solid;
border-width: 1px;
@@ -121,99 +120,120 @@
padding: 17px;
width: 200px;
}
-.now-box li {
+.voice-box li {
font-size: 13px;
font-style: italic;
margin-top: 0px;
}
-.now-box ul {
+.voice-box ul {
margin-bottom: 0px;
}
-.now-img {
+.voice-img {
width: 30px;
margin-bottom: 0px !important;
}
-.now-img-cont {
+.voice-img-cont {
float: left;
margin-right: 10px;
}
-.now-title {
+.voice-title {
font-weight: bold;
margin-top: 7px;
}
-.now-list {
+.voice-list {
font-size: 13px;
margin-bottom: 10px !important;
list-style-type: none;
}
-.now-list li {
+.voice-list li {
font-style: italic;
}
</style>
-<p>An intent allows you to start an activity in another app by describing a simple
-action you'd like to perform (such as "view a map" or "take a picture")
-in an {@link android.content.Intent} object. This type of intent is
-called an <em>implicit</em> intent because it does not specify the app component
-to start, but instead specifies an <em>action</em> and provides some
-<em>data</em> with which to perform the action.</p>
+<p>
+ An intent allows you to start an activity in another app by describing a
+ simple action you'd like to perform (such as "view a map" or "take a
+ picture") in an {@link android.content.Intent} object. This type of intent
+ is called an <em>implicit</em> intent because it does not specify the app
+ component to start, but instead specifies an <em>action</em> and provides
+ some <em>data</em> with which to perform the action.
+</p>
-<p>When you call
-{@link android.content.Context#startActivity startActivity()} or
-{@link android.app.Activity#startActivityForResult startActivityForResult()} and pass it an
-implicit intent, the system <a href="{@docRoot}guide/components/intents-filters.html#Resolution"
->resolves the intent</a> to an app that can handle the intent
-and starts its corresponding {@link android.app.Activity}. If there's more than one app
-that can handle the intent, the system presents the user with a dialog to pick which app
-to use.</p>
+<p>
+ When you call {@link android.content.Context#startActivity startActivity()}
+ or {@link android.app.Activity#startActivityForResult
+ startActivityForResult()} and pass it an implicit intent, the system
+ <a href="{@docRoot}guide/components/intents-filters.html#Resolution">resolves
+ the intent</a> to an app that can handle the intent and starts its
+ corresponding {@link android.app.Activity}. If there's more than one app
+ that can handle the intent, the system presents the user with a dialog to
+ pick which app to use.
+</p>
-<p>This page describes several implicit intents that you can use to perform common actions,
-organized by the type of app that handles the intent. Each section also shows how you can
-create an <a href="{@docRoot}guide/components/intents-filters.html#Receiving">intent filter</a> to
-advertise your app's ability to perform the same action.</p>
+<p>
+ This page describes several implicit intents that you can use to perform
+ common actions, organized by the type of app that handles the intent. Each
+ section also shows how you can create an <a href=
+ "{@docRoot}guide/components/intents-filters.html#Receiving">intent
+ filter</a> to advertise your app's ability to perform the same action.
+</p>
-<p class="caution"><strong>Caution:</strong> If there are no apps on the device that can receive
-the implicit intent, your app will crash when it calls {@link android.content.Context#startActivity
-startActivity()}. To first verify that an app exists to receive the intent, call {@link
-android.content.Intent#resolveActivity resolveActivity()} on your {@link android.content.Intent}
-object. If the result is non-null, there is at least one app that can handle the intent and
-it's safe to call {@link android.content.Context#startActivity startActivity()}. If the result is
-null, you should not use the intent and, if possible, you should disable the feature that invokes
-the intent.</p>
+<p class="caution">
+ <strong>Caution:</strong> If there are no apps on the device that can
+ receive the implicit intent, your app will crash when it calls {@link
+ android.content.Context#startActivity startActivity()}. To first verify that
+ an app exists to receive the intent, call {@link
+ android.content.Intent#resolveActivity resolveActivity()} on your {@link
+ android.content.Intent} object. If the result is non-null, there is at least
+ one app that can handle the intent and it's safe to call {@link
+ android.content.Context#startActivity startActivity()}. If the result is
+ null, you should not use the intent and, if possible, you should disable the
+ feature that invokes the intent.
+</p>
-<p>If you're not familiar with how to create intents or intent filters, you should first read
-<a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>.</p>
+<p>
+ If you're not familiar with how to create intents or intent filters, you
+ should first read <a href=
+ "{@docRoot}guide/components/intents-filters.html">Intents and Intent
+ Filters</a>.
+</p>
-<p>To learn how to fire the intents listed on this page from your development host, see
-<a href="#AdbIntents">Verify Intents with the Android Debug Bridge</a>.</p>
+<p>
+ To learn how to fire the intents listed on this page from your development
+ host, see <a href="#AdbIntents">Verify Intents with the Android Debug
+ Bridge</a>.
+</p>
-<h4>Google Now</h4>
+<h4>Google Voice Actions</h4>
-<p><a href="http://www.google.com/landing/now/">Google Now</a> fires some of the intents listed
-on this page in response to voice commands. For more information, see
-<a href="#Now">Intents Fired by Google Now</a>.</p>
-
-
-
-
-
+<p>
+ <a href="https://developers.google.com/voice-actions/">Google Voice
+ Actions</a> fires some of the intents listed on this page in response to
+ voice commands. For more information, see <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ Intents fired by Google Voice Actions</a>.
+</p>
<h2 id="Clock">Alarm Clock</h2>
-
<h3 id="CreateAlarm">Create an alarm</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img" width="30"
- height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"set an alarm for 7 am"</li>
+ <li>"set an alarm for 7 am"
+ </li>
</ul>
</div>
@@ -301,22 +321,30 @@
<h3 id="CreateTimer">Create a timer</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"set timer for 5 minutes"</li>
+ <li>"set timer for 5 minutes"
+ </li>
</ul>
</div>
-<p>To create a countdown timer, use the {@link android.provider.AlarmClock#ACTION_SET_TIMER}
-action and specify timer details such as the duration using extras defined below.</p>
+<p>
+ To create a countdown timer, use the {@link
+ android.provider.AlarmClock#ACTION_SET_TIMER} action and specify timer
+ details such as the duration using extras defined below.
+</p>
<p class="note"><strong>Note:</strong> This intent was added
in Android 4.4 (API level 19).</p>
@@ -594,28 +622,36 @@
</activity>
</pre>
-<p>When handling this intent, your activity should check for the {@link
-android.provider.MediaStore#EXTRA_OUTPUT} extra in the incoming {@link android.content.Intent},
-then save the captured image or video at the location specified by that extra and call {@link
-android.app.Activity#setResult(int,Intent) setResult()} with an
-{@link android.content.Intent} that includes a compressed thumbnail
-in an extra named <code>"data"</code>.</p>
+<p>
+ When handling this intent, your activity should check for the {@link
+ android.provider.MediaStore#EXTRA_OUTPUT} extra in the incoming {@link
+ android.content.Intent}, then save the captured image or video at the
+ location specified by that extra and call {@link
+ android.app.Activity#setResult(int,Intent) setResult()} with an {@link
+ android.content.Intent} that includes a compressed thumbnail in an extra
+ named <code>"data"</code>.
+</p>
<h3 id="CameraStill">Start a camera app in still image mode</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"take a picture"</li>
+ <li>"take a picture"
+ </li>
</ul>
</div>
@@ -661,17 +697,22 @@
<h3 id="CameraVideo">Start a camera app in video mode</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"record a video"</li>
+ <li>"record a video"
+ </li>
</ul>
</div>
@@ -1348,20 +1389,30 @@
<h3 id="CallCar">Call a car</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"get me a taxi"</li>
- <li>"call me a car"</li>
+ <li>"get me a taxi"
+ </li>
+
+ <li>"call me a car"
+ </li>
</ul>
- <p style="font-size:13px;margin-bottom:0px;margin-top:10px">(Android Wear only)</p>
+
+ <p style="font-size:13px;margin-bottom:0px;margin-top:10px">
+ (Android Wear only)
+ </p>
</div>
<p>To call a taxi, use the
@@ -1548,17 +1599,22 @@
<h3 id="PlaySearch">Play music based on a search query</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"play michael jackson billie jean"</li>
+ <li>"play michael jackson billie jean"
+ </li>
</ul>
</div>
@@ -1861,19 +1917,28 @@
the URI scheme defined below. When the phone app opens, it displays the phone number
but the user must press the <em>Call</em> button to begin the phone call.</p>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"call 555-5555"</li>
- <li>"call bob"</li>
- <li>"call voicemail"</li>
+ <li>"call 555-5555"
+ </li>
+
+ <li>"call bob"
+ </li>
+
+ <li>"call voicemail"
+ </li>
</ul>
</div>
@@ -1947,16 +2012,22 @@
<h3 id="SearchOnApp">Search using a specific app</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30"/></a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"search for cat videos on myvideoapp"</li>
+ <li>"search for cat videos on myvideoapp"
+ </li>
</ul>
</div>
<!-- Video box -->
@@ -1976,7 +2047,7 @@
<dd>
<dl>
<dt><code>"com.google.android.gms.actions.SEARCH_ACTION"</code></dt>
- <dd>Support search queries from Google Now.</dd>
+ <dd>Support search queries from Google Voice Actions.</dd>
</dl>
</dd>
@@ -2207,17 +2278,22 @@
<h3 id="ViewUrl">Load a web URL</h3>
-<!-- Google Now box -->
-<div class="now-box">
- <div class="now-img-cont">
- <a href="#Now">
- <img src="{@docRoot}guide/components/images/voice-icon.png" class="now-img"
- width="30" height="30" alt=""/>
- </a>
+<!-- Google Voice Actions box -->
+<div class="voice-box">
+ <div class="voice-img-cont">
+ <a href=
+ "https://developers.google.com/voice-actions/system/#system_actions_reference">
+ <img src="{@docRoot}guide/components/images/voice-icon.png" class=
+ "voice-img" width="30" height="30" alt=""></a>
</div>
- <p class="now-title">Google Now</p>
+
+ <p class="voice-title">
+ Google Voice Actions
+ </p>
+
<ul>
- <li>"open example.com"</li>
+ <li>"open example.com"
+ </li>
</ul>
</div>
@@ -2307,128 +2383,4 @@
<p>For more information, see
-<a href="{@docRoot}tools/help/shell.html#am">ADB Shell Commands</a>.</p>
-
-
-
-
-
-
-<h2 id="Now">Intents Fired by Google Now</h2>
-
-<p><a href="http://www.google.com/landing/now/">Google Now</a> recognizes many voice commands
-and fires intents for them. As such, users may launch your app with a Google Now voice command
-if your app declares the corresponding intent filter. For example, if your app can
-<a href="#CreateAlarm">set an alarm</a> and you add the corresponding intent filter to your
-manifest file, Google Now lets users choose your app when they request to set an alarm, as
-shown in figure 1.</p>
-
-<img src="{@docRoot}guide/components/images/google-action.png"
- srcset="{@docRoot}guide/components/images/google-action_2x.png 2x"
- width="700" height="241" alt=""/>
-<p class="img-caption"><strong>Figure 1.</strong> Google Now lets users choose from installed
-apps that support a given action.</p>
-
-<p>Google Now recognizes voice commands for the actions listed in table 1. For more information
-about declaring each intent filter, click on the action description.</p>
-
-<p class="table-caption"><strong>Table 1.</strong> Voice commands recognized by Google Now
-(Google Search app v3.6).</p>
-<table>
-<tr>
- <th>Category</th>
- <th>Details and Examples</th>
- <th>Action Name</th>
-</tr>
-<tr>
- <td rowspan="2" style="vertical-align:middle">Alarm</td>
- <td>
- <p><a href="#CreateAlarm">Set alarm</a></p>
- <ul class="now-list">
- <li>"set an alarm for 7 am"</li>
- </ul>
- </td>
- <td>{@link android.provider.AlarmClock#ACTION_SET_ALARM AlarmClock.ACTION_SET_ALARM}</td>
-</tr>
-<tr>
- <td>
- <p><a href="#CreateTimer">Set timer</a></p>
- <ul class="now-list">
- <li>"set a timer for 5 minutes"</li>
- </ul>
- </td>
- <td>{@link android.provider.AlarmClock#ACTION_SET_TIMER AlarmClock.ACTION_SET_TIMER}</td>
-</tr>
-<tr>
- <td style="vertical-align:middle">Communication</td>
- <td>
- <p><a href="#DialPhone">Call a number</a></p>
- <ul class="now-list">
- <li>"call 555-5555"</li>
- <li>"call bob"</li>
- <li>"call voicemail"</li>
- </ul>
- </td>
- <td>{@link android.content.Intent#ACTION_CALL Intent.ACTION_CALL}</td>
-</tr>
-<tr>
- <td style="vertical-align:middle">Local</td>
- <td>
- <p><a href="#CallCar">Book a car</a></p>
- <ul class="now-list">
- <li>"call me a car"</li>
- <li>"book me a taxi"</li>
- </ul>
- </td>
- <td><a href="{@docRoot}reference/com/google/android/gms/actions/ReserveIntents.html#ACTION_RESERVE_TAXI_RESERVATION">
- <code>ReserveIntents<br/>.ACTION_RESERVE_TAXI_RESERVATION</code></a></td>
-</tr>
-<tr>
- <td rowspan="3" style="vertical-align:middle">Media</td>
- <td>
- <p><a href="#PlaySearch">Play music from search</a></p>
- <ul class="now-list">
- <li>"play michael jackson billie jean"</li>
- </ul>
- </td>
- <td>{@link android.provider.MediaStore#INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH MediaStore<br/>.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH}</td>
-</tr>
-<tr>
- <td>
- <p><a href="#CameraStill">Take a picture</a></p>
- <ul class="now-list">
- <li>"take a picture"</li>
- </ul>
- </td>
- <td>{@link android.provider.MediaStore#INTENT_ACTION_STILL_IMAGE_CAMERA MediaStore<br/>.INTENT_ACTION_STILL_IMAGE_CAMERA}</td>
-</tr>
-<tr>
- <td>
- <p><a href="#CameraVideo">Record a video</a></p>
- <ul class="now-list">
- <li>"record a video"</li>
- </ul>
- </td>
- <td>{@link android.provider.MediaStore#INTENT_ACTION_VIDEO_CAMERA MediaStore<br/>.INTENT_ACTION_VIDEO_CAMERA}</td>
-</tr>
-<tr>
- <td style="vertical-align:middle">Search</td>
- <td>
- <p><a href="#SearchOnApp">Search using a specific app</a></p>
- <ul class="now-list">
- <li>"search for cat videos <br/>on myvideoapp"</li>
- </ul>
- </td>
- <td><code>"com.google.android.gms.actions<br/>.SEARCH_ACTION"</code></td>
-</tr>
-<tr>
- <td style="vertical-align:middle">Web browser</td>
- <td>
- <p><a href="#ViewUrl">Open URL</a></p>
- <ul class="now-list">
- <li>"open example.com"</li>
- </ul>
- </td>
- <td>{@link android.content.Intent#ACTION_VIEW Intent.ACTION_VIEW}</td>
-</tr>
-</table>
+<a href="{@docRoot}tools/help/shell.html#am">ADB Shell Commands</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/renderscript/advanced.jd b/docs/html/guide/topics/renderscript/advanced.jd
index 6a72b97..5cc0556 100644
--- a/docs/html/guide/topics/renderscript/advanced.jd
+++ b/docs/html/guide/topics/renderscript/advanced.jd
@@ -63,7 +63,7 @@
<code>llvm</code> compiler that runs as part of an Android build. When your application
runs on a device, the bytecode is then compiled (just-in-time) to machine code by another
<code>llvm</code> compiler that resides on the device. The machine code is optimized for the
- device and also cached, so subsequent uses of the RenderScript enabled application does not
+ device and also cached, so subsequent uses of the RenderScript enabled application do not
recompile the bytecode.</p>
<p>Some key features of the RenderScript runtime libraries include:</p>
@@ -128,7 +128,7 @@
<h3 id="func">Functions</h3>
<p>Functions are reflected into the script class itself, located in
<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. For
-example, if you declare the following function in your RenderScript code:</p>
+example, if you define the following function in your RenderScript code:</p>
<pre>
void touch(float x, float y, float pressure, int id) {
@@ -142,7 +142,7 @@
}
</pre>
-<p>then the following code is generated:</p>
+<p>then the following Java code is generated:</p>
<pre>
public void invoke_touch(float x, float y, float pressure, int id) {
@@ -155,7 +155,7 @@
}
</pre>
<p>
-Functions cannot have a return value, because the RenderScript system is designed to be
+Functions cannot have return values, because the RenderScript system is designed to be
asynchronous. When your Android framework code calls into RenderScript, the call is queued and is
executed when possible. This restriction allows the RenderScript system to function without constant
interruption and increases efficiency. If functions were allowed to have return values, the call
@@ -171,11 +171,11 @@
<p>Variables of supported types are reflected into the script class itself, located in
<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. A set of accessor
-methods are generated for each variable. For example, if you declare the following variable in
+methods is generated for each variable. For example, if you define the following variable in
your RenderScript code:</p>
<pre>uint32_t unsignedInteger = 1;</pre>
- <p>then the following code is generated:</p>
+ <p>then the following Java code is generated:</p>
<pre>
private long mExportVar_unsignedInteger;
@@ -194,7 +194,7 @@
<p>Structs are reflected into their own classes, located in
<code><project_root>/gen/com/example/renderscript/ScriptField_struct_name</code>. This
class represents an array of the <code>struct</code> and allows you to allocate memory for a
- specified number of <code>struct</code>s. For example, if you declare the following struct:</p>
+ specified number of <code>struct</code>s. For example, if you define the following struct:</p>
<pre>
typedef struct Point {
float2 position;
@@ -373,7 +373,7 @@
the array. The RenderScript runtime automatically has access to the newly written memory.
<li>Accessor methods to get and set the values of each field in a struct. Each of these
- accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in
+ accessor methods has an <code>index</code> parameter to specify the <code>struct</code> in
the array that you want to read or write to. Each setter method also has a
<code>copyNow</code> parameter that specifies whether or not to immediately sync this memory
to the RenderScript runtime. To sync any memory that has not been synced, call
@@ -395,10 +395,10 @@
</ul>
<h3 id="pointer">Pointers</h3>
- <p>Pointers are reflected into the script class itself, located in
+ <p>Global pointers are reflected into the script class itself, located in
<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You
can declare pointers to a <code>struct</code> or any of the supported RenderScript types, but a
-<code>struct</code> cannot contain pointers or nested arrays. For example, if you declare the
+<code>struct</code> cannot contain pointers or nested arrays. For example, if you define the
following pointers to a <code>struct</code> and <code>int32_t</code></p>
<pre>
@@ -410,7 +410,7 @@
Point_t *touchPoints;
int32_t *intPointer;
</pre>
- <p>then the following code is generated in:</p>
+ <p>then the following Java code is generated:</p>
<pre>
private ScriptField_Point mExportVar_touchPoints;
@@ -437,7 +437,7 @@
</pre>
<p>A <code>get</code> method and a special method named <code>bind_<em>pointer_name</em></code>
-(instead of a <code>set()</code> method) is generated. This method allows you to bind the memory
+(instead of a <code>set()</code> method) are generated. The <code>bind_<em>pointer_name</em></code> method allows you to bind the memory
that is allocated in the Android VM to the RenderScript runtime (you cannot allocate
memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working
with Allocated Memory</a>.
@@ -521,7 +521,7 @@
describes.</p>
<p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube
- map). You can assign the X,Y,Z dimensions to any positive integer value within the
+ map). You can set the X,Y,Z dimensions to any positive integer value within the
constraints of available memory. A single dimension allocation has an X dimension of
greater than zero while the Y and Z dimensions are zero to indicate not present. For
example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index fe68654..13880ec 100755
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -16,6 +16,13 @@
</ol>
</li>
<li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li>
+ <li><a href="#reduction-in-depth">Reduction Kernels in Depth</a>
+ <ol>
+ <li><a href="#writing-reduction-kernel">Writing a reduction kernel</a></li>
+ <li><a href="#calling-reduction-kernel">Calling a reduction kernel from Java code</a></li>
+ <li><a href="#more-example">More example reduction kernels</a></li>
+ </ol>
+ </li>
</ol>
<h2>Related Samples</h2>
@@ -29,16 +36,18 @@
<p>RenderScript is a framework for running computationally intensive tasks at high performance on
Android. RenderScript is primarily oriented for use with data-parallel computation, although serial
-computationally intensive workloads can benefit as well. The RenderScript runtime will parallelize
-work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing
-you to focus on expressing algorithms rather than scheduling work or load balancing. RenderScript is
+workloads can benefit as well. The RenderScript runtime parallelizes
+work across processors available on a device, such as multi-core CPUs and GPUs. This allows
+you to focus on expressing algorithms rather than scheduling work. RenderScript is
especially useful for applications performing image processing, computational photography, or
computer vision.</p>
<p>To begin with RenderScript, there are two main concepts you should understand:</p>
<ul>
-<li>High-performance compute kernels are written in a C99-derived language.</li>
+<li>High-performance compute kernels are written in a C99-derived language. A <i>compute
+ kernel</i> is a function or collection of functions that you can direct the RenderScript runtime
+ to execute in parallel across a collection of data.</li>
<li>A Java API is used for managing the lifetime of RenderScript resources and controlling kernel
execution.</li>
@@ -48,7 +57,7 @@
<p>A RenderScript kernel typically resides in a <code>.rs</code> file in the
<code><project_root>/src/</code> directory; each <code>.rs</code> file is called a
-script. Every script contains its own set of kernels, functions, and variables. A script can
+<i>script</i>. Every script contains its own set of kernels, functions, and variables. A script can
contain:</p>
<ul>
@@ -57,23 +66,32 @@
<li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that
declares the package name of the Java classes reflected from this script.
-Note that your .rs file must be part of your application package, and not in a
+Note that your <code>.rs</code> file must be part of your application package, and not in a
library project.</li>
-<li>Some number of invokable functions. An invokable function is a single-threaded RenderScript
+<li>Zero or more <strong><i>invokable functions</i></strong>. An invokable function is a single-threaded RenderScript
function that you can call from your Java code with arbitrary arguments. These are often useful for
initial setup or serial computations within a larger processing pipeline.</li>
-<li>Some number of script globals. A script global is equivalent to a global variable in C. You can
+<li><p>Zero or more <strong><i>script globals</i></strong>. A script global is equivalent to a global variable in C. You can
access script globals from Java code, and these are often used for parameter passing to RenderScript
-kernels.</li>
+kernels.</p></li>
-<li>Some number of compute kernels. A kernel is a parallel function that executes across every
-{@link android.renderscript.Element} within an {@link android.renderscript.Allocation}.
+<li><p>Zero or more <strong><i>compute kernels</i></strong>. There are two kinds of compute
+kernels: <i>mapping</i> kernels (also called <i>foreach</i> kernels)
+and <i>reduction</i> kernels.</p>
-<p>A simple kernel may look like the following:</p>
+<p>A <em>mapping kernel</em> is a parallel function that operates on a collection of {@link
+ android.renderscript.Allocation Allocations} of the same dimensions. By default, it executes
+ once for every coordinate in those dimensions. It is typically (but not exclusively) used to
+ transform a collection of input {@link android.renderscript.Allocation Allocations} to an
+ output {@link android.renderscript.Allocation} one {@link android.renderscript.Element} at a
+ time.</p>
-<pre>uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) {
+<ul>
+<li><p>Here is an example of a simple <strong>mapping kernel</strong>:</p>
+
+<pre>uchar4 RS_KERNEL invert(uchar4 in, uint32_t x, uint32_t y) {
uchar4 out = in;
out.r = 255 - in.r;
out.g = 255 - in.g;
@@ -81,40 +99,113 @@
return out;
}</pre>
-<p>In most respects, this is identical to a standard C function. The first notable feature is the
-<code>__attribute__((kernel))</code> applied to the function prototype. This denotes that the
-function is a RenderScript kernel instead of an invokable function. The next feature is the
-<code>in</code> argument and its type. In a RenderScript kernel, this is a special argument that is
-automatically filled in based on the input {@link android.renderscript.Allocation} passed to the
-kernel launch. By default, the kernel is run across an entire {@link
-android.renderscript.Allocation}, with one execution of the kernel body per {@link
-android.renderscript.Element} in the {@link android.renderscript.Allocation}. The third notable
-feature is the return type of the kernel. The value returned from the kernel is automatically
-written to the appropriate location in the output {@link android.renderscript.Allocation}. The
-RenderScript runtime checks to ensure that the {@link android.renderscript.Element} types of the
-input and output Allocations match the kernel's prototype; if they do not match, an exception is
-thrown.</p>
+<p>In most respects, this is identical to a standard C
+ function. The <a href="#RS_KERNEL"><code>RS_KERNEL</code></a> property applied to the
+ function prototype specifies that the function is a RenderScript mapping kernel instead of an
+ invokable function. The <code>in</code> argument is automatically filled in based on the
+ input {@link android.renderscript.Allocation} passed to the kernel launch. The
+ arguments <code>x</code> and <code>y</code> are
+ discussed <a href="#special-arguments">below</a>. The value returned from the kernel is
+ automatically written to the appropriate location in the output {@link
+ android.renderscript.Allocation}. By default, this kernel is run across its entire input
+ {@link android.renderscript.Allocation}, with one execution of the kernel function per {@link
+ android.renderscript.Element} in the {@link android.renderscript.Allocation}.</p>
-<p>A kernel may have an input {@link android.renderscript.Allocation}, an output {@link
-android.renderscript.Allocation}, or both. A kernel may not have more than one input or one output
-{@link android.renderscript.Allocation}. If more than one input or output is required, those objects
-should be bound to <code>rs_allocation</code> script globals and accessed from a kernel or invokable
-function via <code>rsGetElementAt_<em>type</em>()</code> or
-<code>rsSetElementAt_<em>type</em>()</code>.</p>
+<p>A mapping kernel may have one or more input {@link android.renderscript.Allocation
+ Allocations}, a single output {@link android.renderscript.Allocation}, or both. The
+ RenderScript runtime checks to ensure that all input and output Allocations have the same
+ dimensions, and that the {@link android.renderscript.Element} types of the input and output
+ Allocations match the kernel's prototype; if either of these checks fails, RenderScript
+ throws an exception.</p>
-<p>A kernel may access the coordinates of the current execution using the <code>x</code>,
-<code>y</code>, and <code>z</code> arguments. These arguments are optional, but the type of the
-coordinate arguments must be <code>uint32_t</code>.</p></li>
+<p class="note"><strong>NOTE:</strong> Before Android 6.0 (API level 23), a mapping kernel may
+ not have more than one input {@link android.renderscript.Allocation}.</p>
+
+<p>If you need more input or output {@link android.renderscript.Allocation Allocations} than
+ the kernel has, those objects should be bound to <code>rs_allocation</code> script globals
+ and accessed from a kernel or invokable function
+ via <code>rsGetElementAt_<i>type</i>()</code> or <code>rsSetElementAt_<i>type</i>()</code>.</p>
+
+<p><strong>NOTE:</strong> <a id="RS_KERNEL"><code>RS_KERNEL</code></a> is a macro
+ defined automatically by RenderScript for your convenience:</p>
+<pre>
+#define RS_KERNEL __attribute__((kernel))
+</pre>
+</li>
+</ul>
+
+<p>A <em>reduction kernel</em> is a family of functions that operates on a collection of input
+ {@link android.renderscript.Allocation Allocations} of the same dimensions. By default,
+ its <a href="#accumulator-function">accumulator function</a> executes once for every
+ coordinate in those dimensions. It is typically (but not exclusively) used to "reduce" a
+ collection of input {@link android.renderscript.Allocation Allocations} to a single
+ value.</p>
+
+<ul>
+<li><p>Here is an <a id="example-addint">example</a> of a simple <strong>reduction
+kernel</strong> that adds up the {@link android.renderscript.Element Elements} of its
+input:</p>
+
+<pre>#pragma rs reduce(addint) accumulator(addintAccum)
+
+static void addintAccum(int *accum, int val) {
+ *accum += val;
+}</pre>
+
+<p>A reduction kernel consists of one or more user-written functions.
+<code>#pragma rs reduce</code> is used to define the kernel by specifying its name
+(<code>addint</code>, in this example) and the names and roles of the functions that make
+up the kernel (an <code>accumulator</code> function <code>addintAccum</code>, in this
+example). All such functions must be <code>static</code>. A reduction kernel always
+requires an <code>accumulator</code> function; it may also have other functions, depending
+on what you want the kernel to do.</p>
+
+<p>A reduction kernel accumulator function must return <code>void</code> and must have at least
+two arguments. The first argument (<code>accum</code>, in this example) is a pointer to
+an <i>accumulator data item</i> and the second (<code>val</code>, in this example) is
+automatically filled in based on the input {@link android.renderscript.Allocation} passed to
+the kernel launch. The accumulator data item is created by the RenderScript runtime; by
+default, it is initialized to zero. By default, this kernel is run across its entire input
+{@link android.renderscript.Allocation}, with one execution of the accumulator function per
+{@link android.renderscript.Element} in the {@link android.renderscript.Allocation}. By
+default, the final value of the accumulator data item is treated as the result of the
+reduction, and is returned to Java. The RenderScript runtime checks to ensure that the {@link
+android.renderscript.Element} type of the input Allocation matches the accumulator function's
+prototype; if it does not match, RenderScript throws an exception.</p>
+
+<p>A reduction kernel has one or more input {@link android.renderscript.Allocation
+Allocations} but no output {@link android.renderscript.Allocation Allocations}.</p></li>
+
+<p>Reduction kernels are explained in more detail <a href="#reduction-in-depth">here</a>.</p>
+
+<p>Reduction kernels are supported in Android 7.0 (API level 24) and later.</p>
+</li>
+</ul>
+
+<p>A mapping kernel function or a reduction kernel accumulator function may access the coordinates
+of the current execution using the <a id="special-arguments">special arguments</a> <code>x</code>,
+<code>y</code>, and <code>z</code>, which must be of type <code>int</code> or <code>uint32_t</code>.
+These arguments are optional.</p>
+
+<p>A mapping kernel function or a reduction kernel accumulator
+function may also take the optional special argument
+<code>context</code> of type <a
+href='reference/rs_for_each.html#android_rs:rs_kernel_context'>rs_kernel_context</a>.
+It is needed by a family of runtime APIs that are used to query
+certain properties of the current execution -- for example, <a
+href='reference/rs_for_each.html#android_rs:rsGetDimX'>rsGetDimX</a>.
+(The <code>context</code> argument is available in Android 6.0 (API level 23) and later.)</p>
+</li>
<li>An optional <code>init()</code> function. An <code>init()</code> function is a special type of
-invokable function that is run when the script is first instantiated. This allows for some
+invokable function that RenderScript runs when the script is first instantiated. This allows for some
computation to occur automatically at script creation.</li>
-<li>Some number of static script globals and functions. A static script global is equivalent to a
-script global except that it cannot be set from Java code. A static function is a standard C
+<li>Zero or more <strong><i>static script globals and functions</i></strong>. A static script global is equivalent to a
+script global except that it cannot be accessed from Java code. A static function is a standard C
function that can be called from any kernel or invokable function in the script but is not exposed
to the Java API. If a script global or function does not need to be called from Java code, it is
-highly recommended that those be declared <code>static</code>.</li> </ul>
+highly recommended that it be declared <code>static</code>.</li> </ul>
<h4>Setting floating point precision</h4>
@@ -129,13 +220,13 @@
</li>
- <li><code>#pragma rs_fp_relaxed</code> - For apps that don’t require strict IEEE 754-2008
+ <li><code>#pragma rs_fp_relaxed</code>: For apps that don’t require strict IEEE 754-2008
compliance and can tolerate less precision. This mode enables flush-to-zero for denorms and
round-towards-zero.
</li>
- <li><code>#pragma rs_fp_imprecise</code> - For apps that don’t have stringent precision
+ <li><code>#pragma rs_fp_imprecise</code>: For apps that don’t have stringent precision
requirements. This mode enables everything in <code>rs_fp_relaxed</code> along with the
following:
@@ -162,14 +253,21 @@
available on devices running Android 3.0 (API level 11) and higher. </li>
<li><strong>{@link android.support.v8.renderscript}</strong> - The APIs in this package are
available through a <a href="{@docRoot}tools/support-library/features.html#v8">Support
- Library</a>, which allows you to use them on devices running Android 2.2 (API level 8) and
+ Library</a>, which allows you to use them on devices running Android 2.3 (API level 9) and
higher.</li>
</ul>
-<p>We strongly recommend using the Support Library APIs for accessing RenderScript because they
- provide a wider range of device compatibility. Developers targeting specific versions of
- Android can use {@link android.renderscript} if necessary.</p>
+<p>Here are the tradeoffs:</p>
+<ul>
+<li>If you use the Support Library APIs, the RenderScript portion of your application will be
+ compatible with devices running Android 2.3 (API level 9) and higher, regardless of which RenderScript
+ features you use. This allows your application to work on more devices than if you use the
+ native (<strong>{@link android.renderscript}</strong>) APIs.</li>
+<li>Certain RenderScript features are not available through the Support Library APIs.</li>
+<li>If you use the Support Library APIs, you will get (possibly significantly) larger APKs than
+if you use the native (<strong>{@link android.renderscript}</strong>) APIs.</li>
+</ul>
<h3 id="ide-setup">Using the RenderScript Support Library APIs</h3>
@@ -202,7 +300,7 @@
buildToolsVersion "23.0.3"
defaultConfig {
- minSdkVersion 8
+ minSdkVersion 9
targetSdkVersion 19
<strong>
renderscriptTargetApi 18
@@ -250,7 +348,7 @@
<p>Using RenderScript from Java code relies on the API classes located in the
{@link android.renderscript} or the {@link android.support.v8.renderscript} package. Most
-applications follow the same basic usage patterns:</p>
+applications follow the same basic usage pattern:</p>
<ol>
@@ -266,12 +364,12 @@
script.</strong> An {@link android.renderscript.Allocation} is a RenderScript object that provides
storage for a fixed amount of data. Kernels in scripts take {@link android.renderscript.Allocation}
objects as their input and output, and {@link android.renderscript.Allocation} objects can be
-accessed in kernels using <code>rsGetElementAt_<em>type</em>()</code> and
-<code>rsSetElementAt_<em>type</em>()</code> when bound as script globals. {@link
+accessed in kernels using <code>rsGetElementAt_<i>type</i>()</code> and
+<code>rsSetElementAt_<i>type</i>()</code> when bound as script globals. {@link
android.renderscript.Allocation} objects allow arrays to be passed from Java code to RenderScript
code and vice-versa. {@link android.renderscript.Allocation} objects are typically created using
-{@link android.renderscript.Allocation#createTyped} or {@link
-android.renderscript.Allocation#createFromBitmap}.</li>
+{@link android.renderscript.Allocation#createTyped createTyped()} or {@link
+android.renderscript.Allocation#createFromBitmap createFromBitmap()}.</li>
<li><strong>Create whatever scripts are necessary.</strong> There are two types of scripts available
to you when using RenderScript:
@@ -281,9 +379,9 @@
<li><strong>ScriptC</strong>: These are the user-defined scripts as described in <a
href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a> above. Every script has a Java class
reflected by the RenderScript compiler in order to make it easy to access the script from Java code;
-this class will have the name <code>ScriptC_<em>filename</em></code>. For example, if the kernel
-above was located in <code>invert.rs</code> and a RenderScript context was already located in
-<code>mRS</code>, the Java code to instantiate the script would be:
+this class has the name <code>ScriptC_<i>filename</i></code>. For example, if the mapping kernel
+above were located in <code>invert.rs</code> and a RenderScript context were already located in
+<code>mRenderScript</code>, the Java code to instantiate the script would be:
<pre>ScriptC_invert invert = new ScriptC_invert(mRenderScript);</pre></li>
@@ -294,35 +392,926 @@
</ul></li>
<li><strong>Populate Allocations with data.</strong> Except for Allocations created with {@link
-android.renderscript.Allocation#createFromBitmap}, an Allocation will be populated with empty data when it is
-first created. To populate an Allocation, use one of the <code>copy</code> methods in {@link
-android.renderscript.Allocation}.</li>
+android.renderscript.Allocation#createFromBitmap createFromBitmap()}, an Allocation is populated with empty data when it is
+first created. To populate an Allocation, use one of the "copy" methods in {@link
+android.renderscript.Allocation}. The "copy" methods are <a href="#asynchronous-model">synchronous</a>.</li>
-<li><strong>Set any necessary script globals.</strong> Globals may be set using methods in the same
-<code>ScriptC_<em>filename</em></code> class with methods named
-<code>set_<em>globalname</em></code>. For example, in order to set an <code>int</code> named
-<code>elements</code>, use the Java method <code>set_elements(int)</code>. RenderScript objects can
-also be set in kernels; for example, the <code>rs_allocation</code> variable named
-<code>lookup</code> can be set with the method <code>set_lookup(Allocation)</code>.</li>
+<li><strong>Set any necessary script globals.</strong> You may set globals using methods in the
+ same <code>ScriptC_<i>filename</i></code> class named <code>set_<i>globalname</i></code>. For
+ example, in order to set an <code>int</code> variable named <code>threshold</code>, use the
+ Java method <code>set_threshold(int)</code>; and in order to set
+ an <code>rs_allocation</code> variable named <code>lookup</code>, use the Java
+ method <code>set_lookup(Allocation)</code>. The <code>set</code> methods
+ are <a href="#asynchronous-model">asynchronous</a>.</li>
-<li><strong>Launch the appropriate kernels.</strong> Methods to launch a given kernel will be
-reflected in the same <code>ScriptC_<em>filename</em></code> class with methods named
-<code>forEach_<em>kernelname</em>()</code>. These launches are asynchronous, and launches will be
-serialized in the order in which they are launched. Depending on the arguments to the kernel, the
-method will take either one or two Allocations. By default, a kernel will execute over the entire
-input or output Allocation; to execute over a subset of that Allocation, pass an appropriate {@link
-android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> method.
+<li><strong>Launch the appropriate kernels and invokable functions.</strong>
+<p>Methods to launch a given kernel are
+reflected in the same <code>ScriptC_<i>filename</i></code> class with methods named
+<code>forEach_<i>mappingKernelName</i>()</code>
+or <code>reduce_<i>reductionKernelName</i>()</code>.
+These launches are <a href="#asynchronous-model">asynchronous</a>.
+Depending on the arguments to the kernel, the
+method takes one or more Allocations, all of which must have the same dimensions. By default, a
+kernel executes over every coordinate in those dimensions; to execute a kernel over a subset of those coordinates,
+pass an appropriate {@link
+android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> or <code>reduce</code> method.</p>
-<p>Invoked functions can be launched using the <code>invoke_<em>functionname</em></code> methods
-reflected in the same <code>ScriptC_<em>filename</em></code> class.</p></li>
+<p>Launch invokable functions using the <code>invoke_<i>functionName</i></code> methods
+reflected in the same <code>ScriptC_<i>filename</i></code> class.
+These launches are <a href="#asynchronous-model">asynchronous</a>.</p></li>
-<li><strong>Copy data out of {@link android.renderscript.Allocation} objects.</strong> In order to
-access data from an {@link android.renderscript.Allocation} from Java code, that data must be copied
-back to Java buffers using one of the <code>copy</code> methods in {@link
-android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and
-function launches as necessary.</li>
+<li><strong>Retrieve data from {@link android.renderscript.Allocation} objects
+and <i><a href="#javaFutureType">javaFutureType</a></i> objects.</strong>
+In order to
+access data from an {@link android.renderscript.Allocation} from Java code, you must copy that data
+back to Java using one of the "copy" methods in {@link
+android.renderscript.Allocation}.
+In order to obtain the result of a reduction kernel, you must use the <code><i>javaFutureType</i>.get()</code> method.
+The "copy" and <code>get()</code> methods are <a href="#asynchronous-model">synchronous</a>.</li>
-<li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed
+<li><strong>Tear down the RenderScript context.</strong> You can destroy the RenderScript context
with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context
-object to be garbage collected. This will cause any further use of any object belonging to that
+object to be garbage collected. This causes any further use of any object belonging to that
context to throw an exception.</li> </ol>
+
+<h3 id="asynchronous-model">Asynchronous execution model</h3>
+
+<p>The reflected <code>forEach</code>, <code>invoke</code>, <code>reduce</code>,
+ and <code>set</code> methods are asynchronous -- each may return to Java before completing the
+ requested action. However, the individual actions are serialized in the order in which they are launched.</p>
+
+<p>The {@link android.renderscript.Allocation} class provides "copy" methods to copy data to
+ and from Allocations. A "copy" method is synchronous, and is serialized with respect to any
+ of the asynchronous actions above that touch the same Allocation.</p>
+
+<p>The reflected <i><a href="#javaFutureType">javaFutureType</a></i> classes provide
+ a <code>get()</code> method to obtain the result of a reduction. <code>get()</code> is
+ synchronous, and is serialized with respect to the reduction (which is asynchronous).</p>
+
+<h2 id="reduction-in-depth">Reduction Kernels in Depth</h2>
+
+<p><i>Reduction</i> is the process of combining a collection of data into a single
+value. This is a useful primitive in parallel programming, with applications such as the
+following:</p>
+<ul>
+ <li>computing the sum or product over all the data</li>
+ <li>computing logical operations (<code>and</code>, <code>or</code>, <code>xor</code>)
+ over all the data</li>
+ <li>finding the minimum or maximum value within the data</li>
+ <li>searching for a specific value or for the coordinate of a specific value within the data</li>
+</ul>
+
+<p>In Android 7.0 (API level 24) and later, RenderScript supports <i>reduction kernels</i> to allow
+efficient user-written reduction algorithms. You may launch reduction kernels on inputs with
+1, 2, or 3 dimensions.<p>
+
+<p>An example above shows a simple <a href="#example-addint">addint</a> reduction kernel.
+Here is a more complicated <a id="example-findMinAndMax">findMinAndMax</a> reduction kernel
+that finds the locations of the minimum and maximum <code>long</code> values in a
+1-dimensional {@link android.renderscript.Allocation}:</p>
+
+<pre>
+#define LONG_MAX (long)((1UL << 63) - 1)
+#define LONG_MIN (long)(1UL << 63)
+
+#pragma rs reduce(findMinAndMax) \
+ initializer(fMMInit) accumulator(fMMAccumulator) \
+ combiner(fMMCombiner) outconverter(fMMOutConverter)
+
+// Either a value and the location where it was found, or <a href="#INITVAL">INITVAL</a>.
+typedef struct {
+ long val;
+ int idx; // -1 indicates <a href="#INITVAL">INITVAL</a>
+} IndexedVal;
+
+typedef struct {
+ IndexedVal min, max;
+} MinAndMax;
+
+// In discussion below, this initial value { { LONG_MAX, -1 }, { LONG_MIN, -1 } }
+// is called <a id="INITVAL">INITVAL</a>.
+static void fMMInit(MinAndMax *accum) {
+ accum->min.val = LONG_MAX;
+ accum->min.idx = -1;
+ accum->max.val = LONG_MIN;
+ accum->max.idx = -1;
+}
+
+//----------------------------------------------------------------------
+// In describing the behavior of the accumulator and combiner functions,
+// it is helpful to describe hypothetical functions
+// IndexedVal min(IndexedVal a, IndexedVal b)
+// IndexedVal max(IndexedVal a, IndexedVal b)
+// MinAndMax minmax(MinAndMax a, MinAndMax b)
+// MinAndMax minmax(MinAndMax accum, IndexedVal val)
+//
+// The effect of
+// IndexedVal min(IndexedVal a, IndexedVal b)
+// is to return the IndexedVal from among the two arguments
+// whose val is lesser, except that when an IndexedVal
+// has a negative index, that IndexedVal is never less than
+// any other IndexedVal; therefore, if exactly one of the
+// two arguments has a negative index, the min is the other
+// argument. Like ordinary arithmetic min and max, this function
+// is commutative and associative; that is,
+//
+// min(A, B) == min(B, A) // commutative
+// min(A, min(B, C)) == min((A, B), C) // associative
+//
+// The effect of
+// IndexedVal max(IndexedVal a, IndexedVal b)
+// is analogous (greater . . . never greater than).
+//
+// Then there is
+//
+// MinAndMax minmax(MinAndMax a, MinAndMax b) {
+// return MinAndMax(min(a.min, b.min), max(a.max, b.max));
+// }
+//
+// Like ordinary arithmetic min and max, the above function
+// is commutative and associative; that is:
+//
+// minmax(A, B) == minmax(B, A) // commutative
+// minmax(A, minmax(B, C)) == minmax((A, B), C) // associative
+//
+// Finally define
+//
+// MinAndMax minmax(MinAndMax accum, IndexedVal val) {
+// return minmax(accum, MinAndMax(val, val));
+// }
+//----------------------------------------------------------------------
+
+// This function can be explained as doing:
+// *accum = minmax(*accum, IndexedVal(in, x))
+//
+// This function simply computes minimum and maximum values as if
+// INITVAL.min were greater than any other minimum value and
+// INITVAL.max were less than any other maximum value. Note that if
+// *accum is INITVAL, then this function sets
+// *accum = IndexedVal(in, x)
+//
+// After this function is called, both accum->min.idx and accum->max.idx
+// will have nonnegative values:
+// - x is always nonnegative, so if this function ever sets one of the
+// idx fields, it will set it to a nonnegative value
+// - if one of the idx fields is negative, then the corresponding
+// val field must be LONG_MAX or LONG_MIN, so the function will always
+// set both the val and idx fields
+static void fMMAccumulator(MinAndMax *accum, long in, int x) {
+ IndexedVal me;
+ me.val = in;
+ me.idx = x;
+
+ if (me.val <= accum->min.val)
+ accum->min = me;
+ if (me.val >= accum->max.val)
+ accum->max = me;
+}
+
+// This function can be explained as doing:
+// *accum = minmax(*accum, *val)
+//
+// This function simply computes minimum and maximum values as if
+// INITVAL.min were greater than any other minimum value and
+// INITVAL.max were less than any other maximum value. Note that if
+// one of the two accumulator data items is INITVAL, then this
+// function sets *accum to the other one.
+static void fMMCombiner(MinAndMax *accum,
+ const MinAndMax *val) {
+ if ((accum->min.idx < 0) || (val->min.val < accum->min.val))
+ accum->min = val->min;
+ if ((accum->max.idx < 0) || (val->max.val > accum->max.val))
+ accum->max = val->max;
+}
+
+static void fMMOutConverter(int2 *result,
+ const MinAndMax *val) {
+ result->x = val->min.idx;
+ result->y = val->max.idx;
+}
+</pre>
+
+<p class="note"><strong>NOTE:</strong> There are more example reduction
+ kernels <a href="#more-example">here</a>.</p>
+
+<p>In order to run a reduction kernel, the RenderScript runtime creates <em>one or more</em>
+variables called <a id="accumulator-data-items"><strong><i>accumulator data
+items</i></strong></a> to hold the state of the reduction process. The RenderScript runtime
+picks the number of accumulator data items in such a way as to maximize performance. The type
+of the accumulator data items (<i>accumType</i>) is determined by the kernel's <i>accumulator
+function</i> -- the first argument to that function is a pointer to an accumulator data
+item. By default, every accumulator data item is initialized to zero (as if
+by <code>memset</code>); however, you may write an <i>initializer function</i> to do something
+different.</p>
+
+<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a>
+kernel, the accumulator data items (of type <code>int</code>) are used to add up input
+values. There is no initializer function, so each accumulator data item is initialized to
+zero.</p>
+
+<p class="note"><strong>Example:</strong> In
+the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the accumulator data items
+(of type <code>MinAndMax</code>) are used to keep track of the minimum and maximum values
+found so far. There is an initializer function to set these to <code>LONG_MAX</code> and
+<code>LONG_MIN</code>, respectively; and to set the locations of these values to -1, indicating that
+the values are not actually present in the (empty) portion of the input that has been
+processed.</p>
+
+<p>RenderScript calls your accumulator function once for every coordinate in the
+input(s). Typically, your function should update the accumulator data item in some way
+according to the input.</p>
+
+<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a>
+kernel, the accumulator function adds the value of an input Element to the accumulator
+data item.</p>
+
+<p class="note"><strong>Example:</strong> In
+the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the accumulator function
+checks to see whether the value of an input Element is less than or equal to the minimum
+value recorded in the accumulator data item and/or greater than or equal to the maximum
+value recorded in the accumulator data item, and updates the accumulator data item
+accordingly.</p>
+
+<p>After the accumulator function has been called once for every coordinate in the input(s),
+RenderScript must <strong>combine</strong> the <a href="#accumulator-data-items">accumulator
+data items</a> together into a single accumulator data item. You may write a <i>combiner
+function</i> to do this. If the accumulator function has a single input and
+no <a href="#special-arguments">special arguments</a>, then you do not need to write a combiner
+function; RenderScript will use the accumulator function to combine the accumulator data
+items. (You may still write a combiner function if this default behavior is not what you
+want.)</p>
+
+<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a>
+kernel, there is no combiner function, so the accumulator function will be used. This is
+the correct behavior, because if we split a collection of values into two pieces, and we
+add up the values in those two pieces separately, adding up those two sums is the same as
+adding up the entire collection.</p>
+
+<p class="note"><strong>Example:</strong> In
+the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the combiner function
+checks to see whether the minimum value recorded in the "source" accumulator data
+item <code>*val</code> is less then the minimum value recorded in the "destination"
+accumulator data item <code>*accum</code>, and updates <code>*accum</code>
+accordingly. It does similar work for the maximum value. This updates <code>*accum</code>
+to the state it would have had if all of the input values had been accumulated into
+<code>*accum</code> rather than some into <code>*accum</code> and some into
+<code>*val</code>.</p>
+
+<p>After all of the accumulator data items have been combined, RenderScript determines
+the result of the reduction to return to Java. You may write an <i>outconverter
+function</i> to do this. You do not need to write an outconverter function if you want
+the final value of the combined accumulator data items to be the result of the reduction.</p>
+
+<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a> kernel,
+there is no outconverter function. The final value of the combined data items is the sum of
+all Elements of the input, which is the value we want to return.</p>
+
+<p class="note"><strong>Example:</strong> In
+the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the outconverter function
+initializes an <code>int2</code> result value to hold the locations of the minimum and
+maximum values resulting from the combination of all of the accumulator data items.</p>
+
+<h3 id="writing-reduction-kernel">Writing a reduction kernel</h3>
+
+<p><code>#pragma rs reduce</code> defines a reduction kernel by
+specifying its name and the names and roles of the functions that make
+up the kernel. All such functions must be
+<code>static</code>. A reduction kernel always requires an <code>accumulator</code>
+function; you can omit some or all of the other functions, depending on what you want the
+kernel to do.</p>
+
+<pre>#pragma rs reduce(<i>kernelName</i>) \
+ initializer(<i>initializerName</i>) \
+ accumulator(<i>accumulatorName</i>) \
+ combiner(<i>combinerName</i>) \
+ outconverter(<i>outconverterName</i>)
+</pre>
+
+<p>The meaning of the items in the <code>#pragma</code> is as follows:</p>
+<ul>
+
+<li><code>reduce(<i>kernelName</i>)</code> (mandatory): Specifies that a reduction kernel is
+being defined. A reflected Java method <code>reduce_<i>kernelName</i></code> will launch the
+kernel.</li>
+
+<li><p><code>initializer(<i>initializerName</i>)</code> (optional): Specifies the name of the
+initializer function for this reduction kernel. When you launch the kernel, RenderScript calls
+this function once for each <a href="#accumulator-data-items">accumulator data item</a>. The
+function must be defined like this:</p>
+
+<pre>static void <i>initializerName</i>(<i>accumType</i> *accum) { … }</pre>
+
+<p><code>accum</code> is a pointer to an accumulator data item for this function to
+initialize.</p>
+
+<p>If you do not provide an initializer function, RenderScript initializes every accumulator
+data item to zero (as if by <code>memset</code>), behaving as if there were an initializer
+function that looks like this:</p>
+<pre>static void <i>initializerName</i>(<i>accumType</i> *accum) {
+ memset(accum, 0, sizeof(*accum));
+}</pre>
+</li>
+
+<li><p><code><a id="accumulator-function">accumulator(<i>accumulatorName</i>)</a></code>
+(mandatory): Specifies the name of the accumulator function for this
+reduction kernel. When you launch the kernel, RenderScript calls
+this function once for every coordinate in the input(s), to update an
+accumulator data item in some way according to the input(s). The function
+must be defined like this:</p>
+
+<pre>
+static void <i>accumulatorName</i>(<i>accumType</i> *accum,
+ <i>in1Type</i> in1, <i>…,</i> <i>inNType</i> in<i>N</i>
+ <i>[, specialArguments]</i>) { … }
+</pre>
+
+<p><code>accum</code> is a pointer to an accumulator data item for this function to
+modify. <code>in1</code> through <code>in<i>N</i></code> are one <em>or more</em> arguments that
+are automatically filled in based on the inputs passed to the kernel launch, one argument
+per input. The accumulator function may optionally take any of the <a
+href="#special-arguments">special arguments</a>.</p>
+
+<p>An example kernel with multiple inputs is <a href="#dot-product"><code>dotProduct</code></a>.</p>
+</li>
+
+<li><code><a id="combiner-function">combiner(<i>combinerName</i>)</a></code>
+(optional): Specifies the name of the combiner function for this
+reduction kernel. After RenderScript calls the accumulator function
+once for every coordinate in the input(s), it calls this function as many
+times as necessary to combine all accumulator data items into a single
+accumulator data item. The function must be defined like this:</p>
+
+<pre>static void <i>combinerName</i>(<i>accumType</i> *accum, const <i>accumType</i> *other) { … }</pre>
+
+<p><code>accum</code> is a pointer to a "destination" accumulator data item for this
+function to modify. <code>other</code> is a pointer to a "source" accumulator data item
+for this function to "combine" into <code>*accum</code>.</p>
+
+<p class="note"><strong>NOTE:</strong> It is possible
+ that <code>*accum</code>, <code>*other</code>, or both have been initialized but have never
+ been passed to the accumulator function; that is, one or both have never been updated
+ according to any input data. For example, in
+ the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the combiner
+ function <code>fMMCombiner</code> explicitly checks for <code>idx < 0</code> because that
+ indicates such an accumulator data item, whose value is <a href="#INITVAL">INITVAL</a>.</p>
+
+<p>If you do not provide a combiner function, RenderScript uses the accumulator function in its
+place, behaving as if there were a combiner function that looks like this:</p>
+
+<pre>static void <i>combinerName</i>(<i>accumType</i> *accum, const <i>accumType</i> *other) {
+ <i>accumulatorName</i>(accum, *other);
+}</pre>
+
+<p>A combiner function is mandatory if the kernel has more than one input, if the input data
+ type is not the same as the accumulator data type, or if the accumulator function takes one
+ or more <a href="#special-arguments">special arguments</a>.</p>
+</li>
+
+<li><p><code><a id="outconverter-function">outconverter(<i>outconverterName</i>)</a></code>
+(optional): Specifies the name of the outconverter function for this
+reduction kernel. After RenderScript combines all of the accumulator
+data items, it calls this function to determine the result of the
+reduction to return to Java. The function must be defined like
+this:</p>
+
+<pre>static void <i>outconverterName</i>(<i>resultType</i> *result, const <i>accumType</i> *accum) { … }</pre>
+
+<p><code>result</code> is a pointer to a result data item (allocated but not initialized
+by the RenderScript runtime) for this function to initialize with the result of the
+reduction. <i>resultType</i> is the type of that data item, which need not be the same
+as <i>accumType</i>. <code>accum</code> is a pointer to the final accumulator data item
+computed by the <a href="#combiner-function">combiner function</a>.</p>
+
+<p>If you do not provide an outconverter function, RenderScript copies the final accumulator
+data item to the result data item, behaving as if there were an outconverter function that
+looks like this:</p>
+
+<pre>static void <i>outconverterName</i>(<i>accumType</i> *result, const <i>accumType</i> *accum) {
+ *result = *accum;
+}</pre>
+
+<p>If you want a different result type than the accumulator data type, then the outconverter function is mandatory.</p>
+</li>
+
+</ul>
+
+<p>Note that a kernel has input types, an accumulator data item type, and a result type,
+ none of which need to be the same. For example, in
+ the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, the input
+ type <code>long</code>, accumulator data item type <code>MinAndMax</code>, and result
+ type <code>int2</code> are all different.</p>
+
+<h4 id="assume">What can't you assume?</h4>
+
+<p>You must not rely on the number of accumulator data items created by RenderScript for a
+ given kernel launch. There is no guarantee that two launches of the same kernel with the
+ same input(s) will create the same number of accumulator data items.</p>
+
+<p>You must not rely on the order in which RenderScript calls the initializer, accumulator, and
+ combiner functions; it may even call some of them in parallel. There is no guarantee that
+ two launches of the same kernel with the same input will follow the same order. The only
+ guarantee is that only the initializer function will ever see an uninitialized accumulator
+ data item. For example:</p>
+<ul>
+<li>There is no guarantee that all accumulator data items will be initialized before the
+ accumulator function is called, although it will only be called on an initialized accumulator
+ data item.</li>
+<li>There is no guarantee on the order in which input Elements are passed to the accumulator
+ function.</li>
+<li>There is no guarantee that the accumulator function has been called for all input Elements
+ before the combiner function is called.</li>
+</ul>
+
+<p>One consequence of this is that the <a href="#example-findMinAndMax">findMinAndMax</a>
+ kernel is not deterministic: If the input contains more than one occurrence of the same
+ minimum or maximum value, you have no way of knowing which occurrence the kernel will
+ find.</p>
+
+<h4 id="guarantee">What must you guarantee?</h4>
+
+<p>Because the RenderScript system can choose to execute a kernel <a href="#assume">in many
+ different ways</a>, you must follow certain rules to ensure that your kernel behaves the
+ way you want. If you do not follow these rules, you may get incorrect results,
+ nondeterministic behavior, or runtime errors.</p>
+
+<p>The rules below often say that two accumulator data items must have "<a id="the-same">the
+ same value"</a>. What does this mean? That depends on what you want the kernel to do. For
+ a mathematical reduction such as <a href="#example-addint">addint</a>, it usually makes sense
+ for "the same" to mean mathematical equality. For a "pick any" search such
+ as <a href="#example-findMinAndMax">findMinAndMax</a> ("find the location of minimum and
+ maximum input values") where there might be more than one occurrence of identical input
+ values, all locations of a given input value must be considered "the same". You could write
+ a similar kernel to "find the location of <em>leftmost</em> minimum and maximum input values"
+ where (say) a minimum value at location 100 is preferred over an identical minimum value at location
+ 200; for this kernel, "the same" would mean identical <em>location</em>, not merely
+ identical <em>value</em>, and the accumulator and combiner functions would have to be
+ different than those for <a href="#example-findMinAndMax">findMinAndMax</a>.</p>
+
+<strong>The initializer function must create an <i>identity value</i>.</strong> That is,
+ if <code><i>I</i></code> and <code><i>A</i></code> are accumulator data items initialized
+ by the initializer function, and <code><i>I</i></code> has never been passed to the
+ accumulator function (but <code><i>A</i></code> may have been), then
+<ul>
+<li><code><i>combinerName</i>(&<i>A</i>, &<i>I</i>)</code> must
+ leave <code><i>A</i></code> <a href="#the-same">the same</a></li>
+<li><code><i>combinerName</i>(&<i>I</i>, &<i>A</i>)</code> must
+ leave <code><i>I</i></code> <a href="#the-same">the same</a> as <code><i>A</i></code></li>
+</ul>
+<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a>
+ kernel, an accumulator data item is initialized to zero. The combiner function for this
+ kernel performs addition; zero is the identity value for addition.</p>
+<div class="note">
+<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a>
+ kernel, an accumulator data item is initialized
+ to <a href="#INITVAL"><code>INITVAL</code></a>.
+<ul>
+<li><code>fMMCombiner(&<i>A</i>, &<i>I</i>)</code> leaves <code><i>A</i></code> the same,
+ because <code><i>I</i></code> is <code>INITVAL</code>.</li>
+<li><code>fMMCombiner(&<i>I</i>, &<i>A</i>)</code> sets <code><i>I</i></code>
+ to <code><i>A</i></code>, because <code><i>I</i></code> is <code>INITVAL</code>.</li>
+</ul>
+Therefore, <code>INITVAL</code> is indeed an identity value.
+</p></div>
+
+<p><strong>The combiner function must be <i>commutative</i>.</strong> That is,
+ if <code><i>A</i></code> and <code><i>B</i></code> are accumulator data items initialized
+ by the initializer function, and that may have been passed to the accumulator function zero
+ or more times, then <code><i>combinerName</i>(&<i>A</i>, &<i>B</i>)</code> must
+ set <code><i>A</i></code> to <a href="#the-same">the same value</a>
+ that <code><i>combinerName</i>(&<i>B</i>, &<i>A</i>)</code>
+ sets <code><i>B</i></code>.</p>
+<p class="note"><strong>Example:</strong> In the <a href="#example-addint">addint</a>
+ kernel, the combiner function adds the two accumulator data item values; addition is
+ commutative.</p>
+<div class="note">
+<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> kernel,
+<pre>
+fMMCombiner(&<i>A</i>, &<i>B</i>)
+</pre>
+is the same as
+<pre>
+<i>A</i> = minmax(<i>A</i>, <i>B</i>)
+</pre>
+and <code>minmax</code> is commutative, so <code>fMMCombiner</code> is also.
+</p>
+</div>
+
+<p><strong>The combiner function must be <i>associative</i>.</strong> That is,
+ if <code><i>A</i></code>, <code><i>B</i></code>, and <code><i>C</i></code> are
+ accumulator data items initialized by the initializer function, and that may have been passed
+ to the accumulator function zero or more times, then the following two code sequences must
+ set <code><i>A</i></code> to <a href="#the-same">the same value</a>:</p>
+<ul>
+<li><pre>
+<i>combinerName</i>(&<i>A</i>, &<i>B</i>);
+<i>combinerName</i>(&<i>A</i>, &<i>C</i>);
+</pre></li>
+<li><pre>
+<i>combinerName</i>(&<i>B</i>, &<i>C</i>);
+<i>combinerName</i>(&<i>A</i>, &<i>B</i>);
+</pre></li>
+</ul>
+<div class="note">
+<p><strong>Example:</strong> In the <a href="#example-addint">addint</a> kernel, the
+ combiner function adds the two accumulator data item values:
+<ul>
+<li><pre>
+<i>A</i> = <i>A</i> + <i>B</i>
+<i>A</i> = <i>A</i> + <i>C</i>
+// Same as
+// <i>A</i> = (<i>A</i> + <i>B</i>) + <i>C</i>
+</pre></li>
+<li><pre>
+<i>B</i> = <i>B</i> + <i>C</i>
+<i>A</i> = <i>A</i> + <i>B</i>
+// Same as
+// <i>A</i> = <i>A</i> + (<i>B</i> + <i>C</i>)
+// <i>B</i> = <i>B</i> + <i>C</i>
+</li>
+</ul>
+Addition is associative, and so the combiner function is also.
+</p>
+</div>
+<div class="note">
+<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> kernel,
+<pre>
+fMMCombiner(&<i>A</i>, &<i>B</i>)
+</pre>
+is the same as
+<pre>
+<i>A</i> = minmax(<i>A</i>, <i>B</i>)
+</pre>
+So the two sequences are
+<ul>
+<li><pre>
+<i>A</i> = minmax(<i>A</i>, <i>B</i>)
+<i>A</i> = minmax(<i>A</i>, <i>C</i>)
+// Same as
+// <i>A</i> = minmax(minmax(<i>A</i>, <i>B</i>), <i>C</i>)
+</pre></li>
+<li><pre>
+<i>B</i> = minmax(<i>B</i>, <i>C</i>)
+<i>A</i> = minmax(<i>A</i>, <i>B</i>)
+// Same as
+// <i>A</i> = minmax(<i>A</i>, minmax(<i>B</i>, <i>C</i>))
+// <i>B</i> = minmax(<i>B</i>, <i>C</i>)
+</pre></li>
+<code>minmax</code> is associative, and so <code>fMMCombiner</code> is also.
+</p>
+</div>
+
+<p><strong>The accumulator function and combiner function together must obey the <i>basic
+ folding rule</i>.</strong> That is, if <code><i>A</i></code>
+ and <code><i>B</i></code> are accumulator data items, <code><i>A</i></code> has been
+ initialized by the initializer function and may have been passed to the accumulator function
+ zero or more times, <code><i>B</i></code> has not been initialized, and <i>args</i> is
+ the list of input arguments and special arguments for a particular call to the accumulator
+ function, then the following two code sequences must set <code><i>A</i></code>
+ to <a href="#the-same">the same value</a>:</p>
+<ul>
+<li><pre>
+<i>accumulatorName</i>(&<i>A</i>, <i>args</i>); // statement 1
+</pre></li>
+<li><pre>
+<i>initializerName</i>(&<i>B</i>); // statement 2
+<i>accumulatorName</i>(&<i>B</i>, <i>args</i>); // statement 3
+<i>combinerName</i>(&<i>A</i>, &<i>B</i>); // statement 4
+</pre></li>
+</ul>
+<div class="note">
+<p><strong>Example:</strong> In the <a href="#example-addint">addint</a> kernel, for an input value <i>V</i>:
+<ul>
+<li>Statement 1 is the same as <code>A += <i>V</i></code></li>
+<li>Statement 2 is the same as <code>B = 0</code></li>
+<li>Statement 3 is the same as <code>B += <i>V</i></code>, which is the same as <code>B = <i>V</i></code></li>
+<li>Statement 4 is the same as <code>A += B</code>, which is the same as <code>A += <i>V</i></code></li>
+</ul>
+Statements 1 and 4 set <code><i>A</i></code> to the same value, and so this kernel obeys the
+basic folding rule.
+</p>
+</div>
+<div class="note">
+<p><strong>Example:</strong> In the <a href="#example-findMinAndMax">findMinAndMax</a> kernel, for an input
+ value <i>V</i> at coordinate <i>X</i>:
+<ul>
+<li>Statement 1 is the same as <code>A = minmax(A, IndexedVal(<i>V</i>, <i>X</i>))</code></li>
+<li>Statement 2 is the same as <code>B = <a href="#INITVAL">INITVAL</a></code></li>
+<li>Statement 3 is the same as
+<pre>
+B = minmax(B, IndexedVal(<i>V</i>, <i>X</i>))
+</pre>
+which, because <i>B</i> is the initial value, is the same as
+<pre>
+B = IndexedVal(<i>V</i>, <i>X</i>)
+</pre>
+</li>
+<li>Statement 4 is the same as
+<pre>
+A = minmax(A, B)
+</pre>
+which is the same as
+<pre>
+A = minmax(A, IndexedVal(<i>V</i>, <i>X</i>))
+</pre>
+</ul>
+Statements 1 and 4 set <code><i>A</i></code> to the same value, and so this kernel obeys the
+basic folding rule.
+</p>
+</div>
+
+<h3 id="calling-reduction-kernel">Calling a reduction kernel from Java code</h3>
+
+<p>For a reduction kernel named <i>kernelName</i> defined in the
+file <code><i>filename</i>.rs</code>, there are three methods reflected in the
+class <code>ScriptC_<i>filename</i></code>:</p>
+
+<pre>
+// Method 1
+public <i>javaFutureType</i> reduce_<i>kernelName</i>(Allocation ain1, <i>…,</i>
+ Allocation ain<i>N</i>);
+
+// Method 2
+public <i>javaFutureType</i> reduce_<i>kernelName</i>(Allocation ain1, <i>…,</i>
+ Allocation ain<i>N</i>,
+ Script.LaunchOptions sc);
+
+// Method 3
+public <i>javaFutureType</i> reduce_<i>kernelName</i>(<i><a href="#devec">devecSiIn1Type</a></i>[] in1, …,
+ <i><a href="#devec">devecSiInNType</a></i>[] in<i>N</i>);
+</pre>
+
+<p>Here are some examples of calling the <a href="#example-addint">addint</a> kernel:</p>
+<pre>
+ScriptC_example script = new ScriptC_example(mRenderScript);
+
+// 1D array
+// and obtain answer immediately
+int input1[] = <i>…</i>;
+int sum1 = script.reduce_addint(input1).get(); // Method 3
+
+// 2D allocation
+// and do some additional work before obtaining answer
+Type.Builder typeBuilder =
+ new Type.Builder(RS, Element.I32(RS));
+typeBuilder.setX(<i>…</i>);
+typeBuilder.setY(<i>…</i>);
+Allocation input2 = createTyped(RS, typeBuilder.create());
+<i>populateSomehow</i>(input2); // fill in input Allocation with data
+script.result_int result2 = script.reduce_addint(input2); // Method 1
+<i>doSomeAdditionalWork</i>(); // might run at same time as reduction
+int sum2 = result2.get();
+</pre>
+
+<p><strong>Method 1</strong> has one input {@link android.renderscript.Allocation} argument for
+ every input argument in the kernel's <a href="#accumulator-function">accumulator
+ function</a>. The RenderScript runtime checks to ensure that all of the input Allocations
+ have the same dimensions and that the {@link android.renderscript.Element} type of each of
+ the input Allocations matches that of the corresponding input argument of the accumulator
+ function's prototype. If any of these checks fail, RenderScript throws an exception. The
+ kernel executes over every coordinate in those dimensions.</p>
+
+<p><strong>Method 2</strong> is the same as Method 1 except that Method 2 takes an additional
+ argument <code>sc</code> that can be used to limit the kernel execution to a subset of the
+ coordinates.</p>
+
+<p><strong><a id="reduce-method-3">Method 3</a></strong> is the same as Method 1 except that
+ instead of taking Allocation inputs it takes Java array inputs. This is a convenience that
+ saves you from having to write code to explicitly create an Allocation and copy data to it
+ from a Java array. <em>However, using Method 3 instead of Method 1 does not increase the
+ performance of the code</em>. For each input array, Method 3 creates a temporary
+ 1-dimensional Allocation with the appropriate {@link android.renderscript.Element} type and
+ {@link android.renderscript.Allocation#setAutoPadding} enabled, and copies the array to the
+ Allocation as if by the appropriate <code>copyFrom()</code> method of {@link
+ android.renderscript.Allocation}. It then calls Method 1, passing those temporary
+ Allocations.</p>
+<p class="note"><strong>NOTE:</strong> If your application will make multiple kernel calls with
+ the same array, or with different arrays of the same dimensions and Element type, you may improve
+ performance by explicitly creating, populating, and reusing Allocations yourself, instead of
+ by using Method 3.</p>
+<p><strong><i><a id="javaFutureType">javaFutureType</a></i></strong>,
+ the return type of the reflected reduction methods, is a reflected
+ static nested class within the <code>ScriptC_<i>filename</i></code>
+ class. It represents the future result of a reduction
+ kernel run. To obtain the actual result of the run, call
+ the <code>get()</code> method of that class, which returns a value
+ of type <i>javaResultType</i>. <code>get()</code> is <a href="#asynchronous-model">synchronous</a>.</p>
+
+<pre>
+public class ScriptC_<i>filename</i> extends ScriptC {
+ public static class <i>javaFutureType</i> {
+ public <i>javaResultType</i> get() { … }
+ }
+}
+</pre>
+
+<p><strong><i>javaResultType</i></strong> is determined from the <i>resultType</i> of the
+ <a href="#outconverter-function">outconverter function</a>. Unless <i>resultType</i> is an
+ unsigned type (scalar, vector, or array), <i>javaResultType</i> is the directly corresponding
+ Java type. If <i>resultType</i> is an unsigned type and there is a larger Java signed type,
+ then <i>javaResultType</i> is that larger Java signed type; otherwise, it is the directly
+ corresponding Java type. For example:</p>
+<ul>
+<li>If <i>resultType</i> is <code>int</code>, <code>int2</code>, or <code>int[15]</code>,
+ then <i>javaResultType</i> is <code>int</code>, <code>Int2</code>,
+ or <code>int[]</code>. All values of <i>resultType</i> can be represented
+ by <i>javaResultType</i>.</li>
+<li>If <i>resultType</i> is <code>uint</code>, <code>uint2</code>, or <code>uint[15]</code>,
+ then <i>javaResultType</i> is <code>long</code>, <code>Long2</code>,
+ or <code>long[]</code>. All values of <i>resultType</i> can be represented
+ by <i>javaResultType</i>.</li>
+<li>If <i>resultType</i> is <code>ulong</code>, <code>ulong2</code>,
+ or <code>ulong[15]</code>, then <i>javaResultType</i>
+ is <code>long</code>, <code>Long2</code>, or <code>long[]</code>. There are certain values
+ of <i>resultType</i> that cannot be represented by <i>javaResultType</i>.</li>
+</ul>
+
+<p><strong><i>javaFutureType</i></strong> is the future result type corresponding
+ to the <i>resultType</i> of the <a href="#outconverter-function">outconverter
+ function</a>.</p>
+<ul>
+<li>If <i>resultType</i> is not an array type, then <i>javaFutureType</i>
+ is <code>result_<i>resultType</i></code>.</li>
+<li>If <i>resultType</i> is an array of length <i>Count</i> with members of type <i>memberType</i>,
+ then <i>javaFutureType</i> is <code>resultArray<i>Count</i>_<i>memberType</i></code>.</li>
+</ul>
+
+<p>For example:</p>
+
+<pre>
+public class ScriptC_<i>filename</i> extends ScriptC {
+ // for kernels with int result
+ public static class result_int {
+ public int get() { … }
+ }
+
+ // for kernels with int[10] result
+ public static class resultArray10_int {
+ public int[] get() { … }
+ }
+
+ // for kernels with int2 result
+ // note that the Java type name "Int2" is not the same as the script type name "int2"
+ public static class result_int2 {
+ public Int2 get() { … }
+ }
+
+ // for kernels with int2[10] result
+ // note that the Java type name "Int2" is not the same as the script type name "int2"
+ public static class resultArray10_int2 {
+ public Int2[] get() { … }
+ }
+
+ // for kernels with uint result
+ // note that the Java type "long" is a wider signed type than the unsigned script type "uint"
+ public static class result_uint {
+ public long get() { … }
+ }
+
+ // for kernels with uint[10] result
+ // note that the Java type "long" is a wider signed type than the unsigned script type "uint"
+ public static class resultArray10_uint {
+ public long[] get() { … }
+ }
+
+ // for kernels with uint2 result
+ // note that the Java type "Long2" is a wider signed type than the unsigned script type "uint2"
+ public static class result_uint2 {
+ public Long2 get() { … }
+ }
+
+ // for kernels with uint2[10] result
+ // note that the Java type "Long2" is a wider signed type than the unsigned script type "uint2"
+ public static class resultArray10_uint2 {
+ public Long2[] get() { … }
+ }
+}
+</pre>
+
+<p>If <i>javaResultType</i> is an object type (including an array type), each call
+ to <code><i>javaFutureType</i>.get()</code> on the same instance will return the same
+ object.</p>
+
+<p>If <i>javaResultType</i> cannot represent all values of type <i>resultType</i>, and a
+ reduction kernel produces an unrepresentible value,
+ then <code><i>javaFutureType</i>.get()</code> throws an exception.</p>
+
+<h4 id="devec">Method 3 and <i>devecSiInXType</i></h4>
+
+<p><strong><i>devecSiInXType</i></strong> is the Java type corresponding to
+ the <i>inXType</i> of the corresponding argument of
+ the <a href="#accumulator-function">accumulator function</a>. Unless <i>inXType</i> is an
+ unsigned type or a vector type, <i>devecSiInXType</i> is the directly corresponding Java
+ type. If <i>inXType</i> is an unsigned scalar type, then <i>devecSiInXType</i> is the
+ Java type directly corresponding to the signed scalar type of the same
+ size. If <i>inXType</i> is a signed vector type, then <i>devecSiInXType</i> is the Java
+ type directly corresponding to the vector component type. If <i>inXType</i> is an unsigned
+ vector type, then <i>devecSiInXType</i> is the Java type directly corresponding to the
+ signed scalar type of the same size as the vector component type. For example:</p>
+<ul>
+<li>If <i>inXType</i> is <code>int</code>, then <i>devecSiInXType</i>
+ is <code>int</code>.</li>
+<li>If <i>inXType</i> is <code>int2</code>, then <i>devecSiInXType</i>
+ is <code>int</code>. The array is a <em>flattened</em> representation: It has twice as
+ many <em>scalar</em> Elements as the Allocation has 2-component <em>vector</em>
+ Elements. This is the same way that the <code>copyFrom()</code> methods of {@link
+ android.renderscript.Allocation} work.</li>
+<li>If <i>inXType</i> is <code>uint</code>, then <i>deviceSiInXType</i>
+ is <code>int</code>. A signed value in the Java array is interpreted as an unsigned value of
+ the same bitpattern in the Allocation. This is the same way that the <code>copyFrom()</code>
+ methods of {@link android.renderscript.Allocation} work.</li>
+<li>If <i>inXType</i> is <code>uint2</code>, then <i>deviceSiInXType</i>
+ is <code>int</code>. This is a combination of the way <code>int2</code> and <code>uint</code>
+ are handled: The array is a flattened representation, and Java array signed values are
+ interpreted as RenderScript unsigned Element values.</li>
+</ul>
+
+<p>Note that for <a href="#reduce-method-3">Method 3</a>, input types are handled differently
+than result types:</p>
+
+<ul>
+<li>A script's vector input is flattened on the Java side, whereas a script's vector result is not.</li>
+<li>A script's unsigned input is represented as a signed input of the same size on the Java
+ side, whereas a script's unsigned result is represented as a widened signed type on the Java
+ side (except in the case of <code>ulong</code>).</li>
+</ul>
+
+<h3 id="more-example">More example reduction kernels</h3>
+
+<pre id="dot-product">
+#pragma rs reduce(dotProduct) \
+ accumulator(dotProductAccum) combiner(dotProductSum)
+
+// Note: No initializer function -- therefore,
+// each accumulator data item is implicitly initialized to 0.0f.
+
+static void dotProductAccum(float *accum, float in1, float in2) {
+ *accum += in1*in2;
+}
+
+// combiner function
+static void dotProductSum(float *accum, const float *val) {
+ *accum += *val;
+}
+</pre>
+
+<pre>
+// Find a zero Element in a 2D allocation; return (-1, -1) if none
+#pragma rs reduce(fz2) \
+ initializer(fz2Init) \
+ accumulator(fz2Accum) combiner(fz2Combine)
+
+static void fz2Init(int2 *accum) { accum->x = accum->y = -1; }
+
+static void fz2Accum(int2 *accum,
+ int inVal,
+ int x /* special arg */,
+ int y /* special arg */) {
+ if (inVal==0) {
+ accum->x = x;
+ accum->y = y;
+ }
+}
+
+static void fz2Combine(int2 *accum, const int2 *accum2) {
+ if (accum2->x >= 0) *accum = *accum2;
+}
+</pre>
+
+<pre>
+// Note that this kernel returns an array to Java
+#pragma rs reduce(histogram) \
+ accumulator(hsgAccum) combiner(hsgCombine)
+
+#define BUCKETS 256
+typedef uint32_t Histogram[BUCKETS];
+
+// Note: No initializer function --
+// therefore, each bucket is implicitly initialized to 0.
+
+static void hsgAccum(Histogram *h, uchar in) { ++(*h)[in]; }
+
+static void hsgCombine(Histogram *accum,
+ const Histogram *addend) {
+ for (int i = 0; i < BUCKETS; ++i)
+ (*accum)[i] += (*addend)[i];
+}
+
+// Determines the mode (most frequently occurring value), and returns
+// the value and the frequency.
+//
+// If multiple values have the same highest frequency, returns the lowest
+// of those values.
+//
+// Shares functions with the histogram reduction kernel.
+#pragma rs reduce(mode) \
+ accumulator(hsgAccum) combiner(hsgCombine) \
+ outconverter(modeOutConvert)
+
+static void modeOutConvert(int2 *result, const Histogram *h) {
+ uint32_t mode = 0;
+ for (int i = 1; i < BUCKETS; ++i)
+ if ((*h)[i] > (*h)[mode]) mode = i;
+ result->x = mode;
+ result->y = (*h)[mode];
+}
+</pre>
diff --git a/docs/html/guide/topics/ui/notifiers/toasts.jd b/docs/html/guide/topics/ui/notifiers/toasts.jd
index d962727..2262a9a 100644
--- a/docs/html/guide/topics/ui/notifiers/toasts.jd
+++ b/docs/html/guide/topics/ui/notifiers/toasts.jd
@@ -76,16 +76,22 @@
<h2 id="CustomToastView">Creating a Custom Toast View</h2>
-<p>If a simple text message isn't enough, you can create a customized layout for your
-toast notification. To create a custom layout, define a View layout,
-in XML or in your application code, and pass the root {@link android.view.View} object
-to the {@link android.widget.Toast#setView(View)} method.</p>
+<p>
+ If a simple text message isn't enough, you can create a customized layout
+ for your toast notification. To create a custom layout, define a View
+ layout, in XML or in your application code, and pass the root {@link
+ android.view.View} object to the {@link android.widget.Toast#setView(View)}
+ method.
+</p>
-<p>For example, you can create the layout for the toast visible in the screenshot to the right
-with the following XML (saved as <em>toast_layout.xml</em>):</p>
+<p>
+ For example, you can create the layout for the toast visible in the
+ screenshot to the right with the following XML (saved as
+ <em>layout/custom_toast.xml</em>):
+</p>
<pre>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/toast_layout_root"
+ android:id="@+id/custom_toast_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
@@ -105,13 +111,16 @@
</LinearLayout>
</pre>
-<p>Notice that the ID of the LinearLayout element is "toast_layout_root". You must use this
-ID to inflate the layout from the XML, as shown here:</p>
+<p>
+ Notice that the ID of the LinearLayout element is "custom_toast_container".
+ You must use this ID and the ID of the XML layout file "custom_toast" to
+ inflate the layout, as shown here:
+</p>
<pre>
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
- (ViewGroup) findViewById(R.id.toast_layout_root));
+ (ViewGroup) findViewById(R.id.custom_toast_container));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("This is a custom toast");
diff --git a/docs/html/topic/libraries/data-binding/index.jd b/docs/html/topic/libraries/data-binding/index.jd
index 454bb59..ddcc9f2 100644
--- a/docs/html/topic/libraries/data-binding/index.jd
+++ b/docs/html/topic/libraries/data-binding/index.jd
@@ -601,7 +601,7 @@
<import type="com.example.User"/>
<import type="java.util.List"/>
<variable name="user" type="User"/>
- <variable name="userList" type="List<User>"/>
+ <variable name="userList" type="List&lt;User&gt;"/>
</data>
</pre>
<p class="caution">
@@ -945,9 +945,9 @@
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
- <variable name="list" type="List<String>"/>
- <variable name="sparse" type="SparseArray<String>"/>
- <variable name="map" type="Map<String, String>"/>
+ <variable name="list" type="List&lt;String&gt;"/>
+ <variable name="sparse" type="SparseArray&lt;String&gt;"/>
+ <variable name="map" type="Map&lt;String, String&gt;"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
@@ -1247,7 +1247,7 @@
<pre>
<data>
<import type="android.databinding.ObservableMap"/>
- <variable name="user" type="ObservableMap<String, Object>"/>
+ <variable name="user" type="ObservableMap&lt;String, Object&gt;"/>
</data>
…
<TextView
@@ -1277,7 +1277,7 @@
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
- <variable name="user" type="ObservableList<Object>"/>
+ <variable name="user" type="ObservableList&lt;Object&gt;"/>
</data>
…
<TextView
diff --git a/docs/html/topic/libraries/support-library/features.jd b/docs/html/topic/libraries/support-library/features.jd
index 0f63bf6..614392e 100755
--- a/docs/html/topic/libraries/support-library/features.jd
+++ b/docs/html/topic/libraries/support-library/features.jd
@@ -7,7 +7,15 @@
<h2>In this document</h2>
<ol>
- <li><a href="#v4">v4 Support Library</a></li>
+ <li><a href="#v4">v4 Support Libraries</a>
+ <ol>
+ <li><a href="#v4-compat">v4 compat library</a></li>
+ <li><a href="#v4-core-utils">v4 core-utils library</a></li>
+ <li><a href="#v4-core-ui">v4 core-ui library</a></li>
+ <li><a href="#v4-media-compat">v4 media-compat library</a></li>
+ <li><a href="#v4-fragment">v4 fragment library</a></li>
+ </ol>
+ </li>
<li><a href="#multidex">Multidex Support Library</a></li>
<li><a href="#v7">v7 Support Libraries</a>
<ol>
@@ -63,94 +71,115 @@
include the library in your application.</p>
-<h2 id="v4">v4 Support Library</h2>
-
-<p>This library is designed to be used with Android 1.6 (API level 4) and higher. It includes the
- largest set of APIs compared to the other libraries, including support for application components,
- user interface features, accessibility, data handling, network connectivity, and programming
- utilities. Here are a few of the key classes included in the v4 library:</p>
-
-<ul>
- <li>App Components
- <ul>
- <li>{@link android.support.v4.app.Fragment}
- - Adds support for encapsulation of user interface and functionality
- with Fragments, enabling
- applications to provide layouts that adjust between small and
- large-screen devices.
- </li>
-
- <li>{@link android.support.v4.app.NotificationCompat} - Adds support for rich notification
- features.</li>
- <li>{@link android.support.v4.content.LocalBroadcastManager} - Allows applications to easily
- register for and receive intents within a single application without broadcasting them
- globally.</li>
- </ul>
- </li>
- <li>User Interface
- <ul>
- <li>{@link android.support.v4.view.ViewPager} - Adds a
- {@link android.view.ViewGroup} that manages the layout for the
- child views, which the user can swipe between.</li>
- <li>{@link android.support.v4.view.PagerTitleStrip}
- - Adds a non-interactive title strip, that can be added as a child of
- {@link android.support.v4.view.ViewPager}.</li>
- <li>{@link android.support.v4.view.PagerTabStrip} - Adds a
- navigation widget for switching between paged views, that can also be used with
- {@link android.support.v4.view.ViewPager}.</li>
- <li>{@link android.support.v4.widget.DrawerLayout} - Adds
- support for creating a <a href="{@docRoot}training/implementing-navigation/nav-drawer.html"
- >Navigation Drawer</a> that can be pulled in from the edge of a window.</li>
- <li>{@link android.support.v4.widget.SlidingPaneLayout}
- - Adds widget for creating linked summary and detail views that
- appropriately adapt to various screen sizes.</li>
- </ul>
- </li>
- <li>Accessibility
- <ul>
- <li>{@link android.support.v4.widget.ExploreByTouchHelper}
- - Adds a helper class for implementing accessibility support for custom views.</li>
- <li>{@link android.support.v4.view.accessibility.AccessibilityEventCompat} - Adds support for
- {@link android.view.accessibility.AccessibilityEvent}. For more information about implementing
- accessibility, see <a href="{@docRoot}guide/topics/ui/accessibility/index.html"
- >Accessibility</a>.</li>
-
- <li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat} - Adds support
- for {@link android.view.accessibility.AccessibilityNodeInfo}.</li>
- <li>{@link android.support.v4.view.accessibility.AccessibilityNodeProviderCompat} - Adds
- support for {@link android.view.accessibility.AccessibilityNodeProvider}.</li>
- <li>{@link android.support.v4.view.AccessibilityDelegateCompat} - Adds support for
- {@link android.view.View.AccessibilityDelegate}.</li>
- </ul>
- </li>
- <li>Content
- <ul>
- <li>{@link android.support.v4.content.Loader} - Adds support for asynchronous loading of data.
- The library also provides concrete implementations of this class, including
- {@link android.support.v4.content.CursorLoader} and
- {@link android.support.v4.content.AsyncTaskLoader}.</li>
- <li>{@link android.support.v4.content.FileProvider} - Adds support for sharing of private
- files between applications.</li>
- </ul>
- </li>
-</ul>
+<h2 id="v4">v4 Support Libraries</h2>
<p>
- There are many other APIs included in this library. For complete, detailed information about the
- v4 Support Library APIs, see the {@link android.support.v4.app android.support.v4} package in the
- API reference.
+ These libraries are designed to be used with Android 2.3 (API level 9) and
+ higher. They include the largest set of APIs compared to the other libraries,
+ including support for application components, user interface features,
+ accessibility, data handling, network connectivity, and programming
+ utilities.
</p>
-<p class="caution"><strong>Caution:</strong> Using dynamic dependencies, especially for higher version
-numbers, can cause unexpected version updates and regression incompatibilities.</p>
+<p>
+ For complete, detailed information about the classes and methods provided by
+ the v4 support libraries, see the {@link android.support.v4.app
+ android.support.v4} package in the API reference.
+</p>
+
+
+<p class="note">
+ <strong>Note:</strong> Prior to Support Library revision 24.2.0, there was a
+ single v4 support library. That library was divided into multiple modules to
+ improve efficiency. For backwards compatibility, if you list
+ <code>support-v4</code> in your Gradle script, your APK will include all of
+ the v4 modules. However, to reduce APK size, we recommend that you just list
+ the specific modules your app needs.
+</p>
+
+<h3 id="v4-compat">v4 compat library</h3>
+
+<p>
+ Provides compatibility wrappers for a number of framework APIs, such as
+ <code>Context.obtainDrawable()</code> and
+ <code>View.performAccessibilityAction()</code>.
+</p>
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:support-v4:24.1.1
+com.android.support:support-compat:24.2.0
</pre>
+<h3 id="v4-core-utils">v4 core-utils library</h3>
+<p>
+ Provides a number of utility classes, such as {@link
+ android.support.v4.content.AsyncTaskLoader} and {@link
+ android.support.v4.content.PermissionChecker}.
+</p>
+
+<p>
+ The Gradle build script dependency identifier for this library is as follows:
+</p>
+
+<pre>
+com.android.support:support-core-utils:24.2.0
+</pre>
+
+<h3 id="v4-core-ui">v4 core-ui library</h3>
+
+<p>
+ Implements a variety of UI-related components, such as {@link
+ android.support.v4.view.ViewPager}, {@link
+ android.support.v4.widget.NestedScrollView}, and {@link
+ android.support.v4.widget.ExploreByTouchHelper}.
+</p>
+
+<p>
+ The Gradle build script dependency identifier for this library is as follows:
+</p>
+
+<pre>
+com.android.support:support-core-ui:24.2.0
+</pre>
+
+<h3 id="v4-media-compat">v4 media-compat library</h3>
+
+<p>
+ Backports portions of the <a href=
+ "/reference/android/media/package-summary.html">media</a> framework,
+ including {@link android.media.browse.MediaBrowser} and {@link
+ android.media.session.MediaSession}.
+</p>
+
+<p>
+ The Gradle build script dependency identifier for this library is as follows:
+</p>
+
+<pre>
+com.android.support:support-media-compat:24.2.0
+</pre>
+
+<h3 id="v4-fragment">v4 fragment library</h3>
+
+<p>
+ Adds support for encapsulation of user interface and functionality with
+ <a href=
+ "/guide/components/fragments.html">fragments</a>,
+ enabling applications to provide layouts that adjust between small and
+ large-screen devices. This module has dependencies on <a href=
+ "#v4-compat">compat</a>, <a href="#v4-core-utils">core-utils</a>, <a href=
+ "#v4-core-ui">core-ui</a>, and <a href="#v4-media-compat">media-compat</a>.
+</p>
+
+<p>
+ The Gradle build script dependency identifier for this library is as follows:
+</p>
+
+<pre>
+com.android.support:support-fragment:24.2.0
+</pre>
<h2 id="multidex">Multidex Support Library</h2>
@@ -173,7 +202,7 @@
<h2 id="v7">v7 Support Libraries</h2>
-<p>There are several libraries designed to be used with Android 2.1 (API level 7) and higher.
+<p>There are several libraries designed to be used with Android 2.3 (API level 9) and higher.
These libraries provide specific feature sets and can be included in your application
independently from each other.</p>
@@ -216,7 +245,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:appcompat-v7:24.1.1
+com.android.support:appcompat-v7:24.2.0
</pre>
@@ -231,7 +260,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:cardview-v7:24.1.1
+com.android.support:cardview-v7:24.2.0
</pre>
@@ -247,7 +276,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:gridlayout-v7:24.1.1
+com.android.support:gridlayout-v7:24.2.0
</pre>
@@ -270,7 +299,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:mediarouter-v7:24.1.1
+com.android.support:mediarouter-v7:24.2.0
</pre>
<p class="caution">The v7 mediarouter library APIs introduced in Support Library
@@ -290,7 +319,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:palette-v7:24.1.1
+com.android.support:palette-v7:24.2.0
</pre>
@@ -306,7 +335,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:recyclerview-v7:24.1.1
+com.android.support:recyclerview-v7:24.2.0
</pre>
@@ -329,18 +358,18 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:preference-v7:24.1.1
+com.android.support:preference-v7:24.2.0
</pre>
<h2 id="v8">v8 Support Library</h2>
-<p>This library is designed to be used with Android 2.2 (API level 8) and higher.
+<p>This library is designed to be used with Android 2.3 (API level 9) and higher.
This library provides specific feature sets and can be included in your application
independently from other libraries.</p>
<h3 id="v8-renderscript">v8 renderscript library</h3>
-<p>This library is designed to be used with Android (API level 8) and higher. It adds support for
+<p>This library is designed to be used with Android 2.3 (API level 9) and higher. It adds support for
the <a href="{@docRoot}guide/topics/renderscript/compute.html">RenderScript</a> computation
framework. These APIs are included in the {@link android.support.v8.renderscript} package. You
should be aware that the steps for including these APIs in your application is <em>very
@@ -380,7 +409,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:support-v13:24.1.1
+com.android.support:support-v13:24.2.0
</pre>
@@ -406,7 +435,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:preference-v14:24.1.1
+com.android.support:preference-v14:24.2.0
</pre>
@@ -429,7 +458,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:preference-leanback-v17:24.1.1
+com.android.support:preference-leanback-v17:24.2.0
</pre>
@@ -465,7 +494,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:leanback-v17:24.1.1
+com.android.support:leanback-v17:24.2.0
</pre>
@@ -480,7 +509,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:support-annotations:24.1.1
+com.android.support:support-annotations:24.2.0
</pre>
@@ -498,7 +527,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:design:24.1.1
+com.android.support:design:24.2.0
</pre>
@@ -519,7 +548,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:customtabs:24.1.1
+com.android.support:customtabs:24.2.0
</pre>
@@ -543,7 +572,7 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:percent:24.1.1
+com.android.support:percent:24.2.0
</pre>
@@ -566,5 +595,5 @@
<p>The Gradle build script dependency identifier for this library is as follows:</p>
<pre>
-com.android.support:recommendation:24.1.1
+com.android.support:recommendation:24.2.0
</pre>
diff --git a/docs/html/topic/libraries/support-library/revisions.jd b/docs/html/topic/libraries/support-library/revisions.jd
index 3b25fb0..4e14c70 100644
--- a/docs/html/topic/libraries/support-library/revisions.jd
+++ b/docs/html/topic/libraries/support-library/revisions.jd
@@ -6,9 +6,324 @@
<p>This page provides details about the Support Library package releases.</p>
<div class="toggle-content opened">
- <p id="rev24-1-1">
+ <p id="rev24-2-0">
<a href="#" onclick="return toggleContent(this)"><img src=
"{@docRoot}assets/images/styles/disclosure_up.png" class=
+ "toggle-content-img" alt="">Android Support Library, revision 24.2.0</a>
+ <em>(August 2016)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+<p>Release 24.2.0 contains the following changes:</p>
+
+<ul>
+ <li><a href="#24-2-0-v4-refactor">v4 Support Library split</a></li>
+ <li><a href="#24-2-0-api-updates">API updates</a></li>
+ <li><a href="#24-2-0-behavior">Behavior changes</a></li>
+ <li><a href="#24-2-0-deprecations">Deprecations</a></li>
+ <li><a href="#24-2-0-bugfixes">Bug fixes</a></li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Release 24.2.0 removes support for
+ Android 2.2 (API level 8) and lower. Classes and methods that exist only to
+ serve those system versions are now marked as deprecated and should no longer
+ be used. These deprecated classes and methods may be removed in a future
+ release.
+</p>
+
+<h3 id="24-2-0-v4-refactor">v4 Support Library split</h3>
+
+<p>With this release, the <a href="features.html#v4">v4 Support Library</a> has
+ been split into several smaller modules:</p>
+
+<dl>
+ <dt>
+ <code>support-compat</code>
+ </dt>
+
+ <dd>
+ Provides compatibility wrappers for new framework APIs, such as
+ <code>Context.getDrawable()</code> and
+ <code>View.performAccessibilityAction()</code>.
+ </dd>
+
+ <dt>
+ <code>support-core-utils</code>
+ </dt>
+
+ <dd>
+ Provides a number of utility classes, such as {@link
+ android.support.v4.content.AsyncTaskLoader} and {@link
+ android.support.v4.content.PermissionChecker}.
+ </dd>
+
+ <dt>
+ <code>support-core-ui</code>
+ </dt>
+
+ <dd>
+ Implements a variety of UI-related components, such as {@link
+ android.support.v4.view.ViewPager}, {@link
+ android.support.v4.widget.NestedScrollView}, and {@link
+ android.support.v4.widget.ExploreByTouchHelper}.
+ </dd>
+
+ <dt>
+ <code>support-media-compat</code>
+ </dt>
+
+ <dd>
+ Backports portions of the <a href=
+ "/reference/android/media/package-summary.html">media</a> framework,
+ including {@link android.media.browse.MediaBrowser} and {@link
+ android.media.session.MediaSession}.
+ </dd>
+
+ <dt>
+ <code>support-fragment</code>
+ </dt>
+
+ <dd>
+ Backports the <a href=
+ "/guide/components/fragments.html">fragment</a>
+ framework. This module has dependencies on <code>support-compat</code>,
+ <code>support-core-utils</code>, <code>support-core-ui</code>, and
+ <code>support-media-compat</code>.
+ </dd>
+</dl>
+
+<p>For backwards compatibility, if you list <code>support-v4</code> in your
+Gradle script, your APK will include all of these modules. However, to reduce
+APK size, we recommend that you just list the specific modules your app needs.
+</p>
+
+<h3 id="24-2-0-api-updates">API updates</h3>
+
+<ul>
+ <li>Clients using <a href="features.html#custom-tabs">Custom Tabs</a> can
+ control whether Instant Apps should open. (Note that Instant Apps are not yet
+ generally available.) To enable or disable Instant Apps, call <a href=
+ "/reference/android/support/customtabs/CustomTabsIntent.Builder.html#setInstantAppsEnabled(boolean)">
+ <code>CustomTabsIntent.Builder.setInstantAppsEnabled()</code></a> or
+ specify <a href=
+ "/reference/android/support/customtabs/CustomTabsIntent.html#EXTRA_ENABLE_INSTANT_APPS">
+ <code>EXTRA_ENABLE_INSTANT_APPS</code></a>. By default, Custom Tabs will
+ default to enabling Instant Apps, when that feature becomes available.
+ </li>
+
+ <li>{@link android.support.design.widget.TextInputLayout} adds support for
+ the <a href=
+ "https://material.google.com/components/text-fields.html#text-fields-password-input">
+ password visibility toggle</a> from the material design specification.
+ </li>
+
+ <li>The new <a href=
+ "/reference/android/support/transition/package-summary.html"
+ ><code>android.support.transition</code></a>
+ package backports the <a href=
+ "/training/transitions/index.html">Transitions</a> framework to API levels 14
+ and higher. For more information, see the <a href=
+ "/reference/android/support/transition/package-summary.html"
+ ><code>android.support.transition</code></a> reference.
+ </li>
+
+ <li>The <a href="features.html#custom-tabs">Custom Tabs support library</a>
+ adds support for using {@link android.widget.RemoteViews} in the secondary
+ toolbar. The existing {@link
+ android.support.customtabs.CustomTabsSession#setToolbarItem setToolbarItem()}
+ method is now deprecated.
+ </li>
+
+ <li>{@link android.support.v7.content.res.AppCompatResources} adds the
+ ability to load a <code><vector></code> (on API level 9 and higher) or
+ <code><animated-vector></code> (on API level 11 and higher) from a
+ resource ID, by using the new <a href=
+ "/reference/android/support/v7/content/res/AppCompatResources.html#getDrawable(android.content.Context,%20int)"
+ ><code>getDrawable()</code></a> method.
+ </li>
+
+ <li>{@link android.support.design.widget.CoordinatorLayout} now supports
+ defining inset views, and specifying that other views should dodge the inset
+ views. This allows apps to replicate behavior patterns similar to the way
+ {@link android.support.design.widget.FloatingActionButton} moves out of the
+ way of a {@link android.support.design.widget.Snackbar}, but for any
+ arbitrary view children. For more information, see the <a href=
+ "/reference/android/support/design/widget/CoordinatorLayout.LayoutParams.html#insetEdge">
+ <code>LayoutParams.insetEdge</code></a> and <a href=
+ "/reference/android/support/design/widget/CoordinatorLayout.LayoutParams.html#dodgeInsetEdges">
+ <code>LayoutParams.dodgeInsetEdges</code></a> reference documentation.
+ </li>
+
+ <li>The new <a href="/reference/android/support/v7/util/DiffUtil.html"><code>
+ DiffUtil</code></a> class can calculate the difference between two
+ collections, and can dispatch a list of update operations that are suitable
+ to be consumed by a {@link android.support.v7.widget.RecyclerView.Adapter}.
+ </li>
+
+ <li>
+ <a href=
+ "/reference/android/support/v7/widget/RecyclerView.OnFlingListener.html"><code>
+ RecyclerView.OnFlingListener</code></a> has been added to support custom
+ behavior in response to flings. The <a href=
+ "/reference/android/support/v7/widget/SnapHelper.html"><code>SnapHelper</code></a>
+ class provides an implementation specifically for snapping child views, and
+ the <a href=
+ "/reference/android/support/v7/widget/LinearSnapHelper.html"><code>LinearSnapHelper</code></a>
+ class extends this implementation to provide center-aligned snapping
+ behavior similar to {@link android.support.v4.view.ViewPager}.
+ </li>
+
+</ul>
+
+<h3 id="24-2-0-behavior">Behavior changes</h3>
+
+<ul>
+ <li>If you use the appcompat library's day/night functionality, the system
+ now automatically recreates your activity whenever the day/night mode changes
+ (either because of the time of day, or because of a call to {@link
+ android.support.v7.app.AppCompatDelegate#setLocalNightMode
+ AppCompatDelegate.setLocalNightMode()}).
+ </li>
+
+ <li>{@link android.support.design.widget.Snackbar} now draws behind the
+ navigation bar if the status bar is translucent.
+ </li>
+</ul>
+
+<h3 id="24-2-0-deprecations">Deprecations</h3>
+
+<p>Deprecated classes and methods are subject to removal in a future release. You should migrate away from these APIs as soon as possible.</p>
+
+<ul>
+ <li>Several methods on the following classes were only required for API 8 and
+ lower, and should no longer be used. Instead, use the framework
+ implementations.
+ <ul>
+ <li>{@link android.support.v4.view.KeyEventCompat}: Replace with {@link
+ android.view.KeyEvent}
+ </li>
+
+ <li>{@link android.support.v4.view.MotionEventCompat}: Use {@link
+ android.view.MotionEvent}
+ </li>
+
+ <li>{@link android.support.v4.view.ViewCompat}: Use {@link
+ android.view.View}
+ </li>
+
+ <li>{@link android.support.v4.view.ViewConfigurationCompat}: Use {@link
+ android.view.ViewConfiguration}
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ {@link android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat#getDescription
+ AccessibilityServiceInfoCompat.getDescription()}
+ has been deprecated in favor of
+ <a href="/reference/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.html#loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager)"><code>loadDescription()</code></a>
+ which returns a correctly localized description.
+ </li>
+
+ <li>You should not instantiate the <code>ActivityCompat</code> class
+ directly. The non-static <code>getReferrer(Activity)</code> method will be
+ made static in an upcoming release.
+ </li>
+
+ <li>{@link android.support.design.widget.CoordinatorLayout.Behavior#isDirty
+ CoordinatorLayout.Behavior.isDirty()} has been deprecated and is no longer
+ called by {@link android.support.design.widget.CoordinatorLayout}. Any
+ implementations, as well as any calls to this method, should be removed.
+ </li>
+
+ <li>{@link android.support.v4.media.session.MediaSessionCompat#obtain
+ MediaSessionCompat.obtain()} has been deprecated and replaced with the more
+ appropriately-named method
+ <a href="/reference/android/support/v4/media/session/MediaSessionCompat.html#fromMediaSession"><code>fromMediaSession()</code></a>.
+ </li>
+
+ <li>{@link
+ android.support.v4.media.session.MediaSessionCompat.QueueItem#obtain
+ MediaSessionCompat.QueueItem.obtain()} has been deprecated and replaced with
+ the more appropriately-named method
+ <a href="/reference/android/support/v4/media/session/MediaSessionCompat.QueueItem.html#fromQueueItem"><code>fromQueueItem()</code></a>.
+ </li>
+
+ <li>Several abstract classes have been deprecated and replaced with
+ interfaces that more closely reflect their framework equivalents.
+ <ul>
+ <li>{@link
+ android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat}
+ has been replaced by the <a href=
+ "/reference/android/support/v4/view/accessibility/AccessibilityManagerCompat.AccessibilityStateChangeListener.html">
+ <code>AccessibilityManagerCompat.AccessibilityStateChangeListener</code></a>
+ interface.
+ </li>
+
+ <li>{@link
+ android.support.v4.widget.SearchViewCompat.OnCloseListenerCompat} has
+ been replaced by the <a
+ href="/reference/android/support/v4/widget/SearchViewCompat.OnCloseListener.html"
+ ><code>SearchViewCompat.OnCloseListener</code></a> interface.
+ </li>
+
+ <li>{@link
+ android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat }
+ has been replaced by the <a
+ href="/reference/android/support/v4/widget/SearchViewCompat.OnQueryTextListener.html"
+ ><code>SearchViewCompat.OnQueryTextListener</code></a>
+ interface.
+ </li>
+ </ul>
+ </li>
+
+ <li>{@link android.support.customtabs.CustomTabsSession#setToolbarItem
+ CustomTabsSession.setToolbarItem()} has been deprecated and replaced by the
+ RemoteViews-based <a href=
+ "/reference/android/support/customtabs/CustomTabsSession.html#setSecondaryToolbarViews">
+ <code>setSecondaryToolbarViews()</code></a>.
+ </li>
+</ul>
+
+<h3 id="24-2-0-bugfixes">Bug fixes</h3>
+
+<p>The following known issues have been fixed with release 24.2.0:</p>
+
+<ul>
+ <li>Ensure <code>SwipeRefreshLayout</code> indicator is shown when
+ <code>setRefreshing(true)</code> is called before the first measurement pass
+ (<a href="https://code.google.com/p/android/issues/detail?id=77712">AOSP
+ issue 77712</a>)
+ </li>
+
+ <li>Prevent <code>TabLayout</code> from flickering when changing pages
+ (<a href="https://code.google.com/p/android/issues/detail?id=180454">AOSP
+ issue 180454</a>)
+ </li>
+
+ <li>Avoid <code>ClassNotFoundException</code> when unmarshalling
+ <code>SavedState</code> on API level 11 and lower (<a href=
+ "https://code.google.com/p/android/issues/detail?id=196430">AOSP issue
+ 196430</a>)
+ </li>
+</ul>
+
+<p>
+ A complete list of public bug fixes is available on the <a href=
+ "https://code.google.com/p/android/issues/list?can=1&q=Component%3DSupport-Libraries+Target%3DSupport-24.2.0">
+ AOSP Issue Tracker</a>.
+</p>
+
+ </div>
+</div>
+
+<!-- end of collapsible section: 24.2.0 -->
+
+<div class="toggle-content closed">
+ <p id="rev24-1-1">
+ <a href="#" onclick="return toggleContent(this)"><img src=
+ "{@docRoot}assets/images/styles/disclosure_down.png" class=
"toggle-content-img" alt="">Android Support Library, revision 24.1.1</a>
<em>(July 2016)</em>
</p>
@@ -76,7 +391,7 @@
<ul>
<li>TabLayout.setCustomView(null) results in NullPointerException
(<a href="https://code.google.com/p/android/issues/detail?id=214753">AOSP
- issue</a>)
+ issue 214753</a>)
</li>
<li>TabLayout incorrectly highlights custom tabs (<a href=
diff --git a/docs/html/topic/libraries/support-library/setup.jd b/docs/html/topic/libraries/support-library/setup.jd
index 0cb9389..adb263c 100755
--- a/docs/html/topic/libraries/support-library/setup.jd
+++ b/docs/html/topic/libraries/support-library/setup.jd
@@ -85,17 +85,24 @@
<li>Make sure you have downloaded the <strong>Android Support Repository</strong>
using the <a href="#download">SDK Manager</a>.</li>
<li>Open the {@code build.gradle} file for your application.</li>
- <li>Add the support library to the {@code dependencies} section. For example, to add the v4
- support library, add the following lines:
+ <li>Add the support library to the {@code dependencies} section. For
+ example, to add the v4 core-utils library, add the following lines:
<pre>
dependencies {
...
- <b>compile "com.android.support:support-v4:24.1.1"</b>
+ <b>compile "com.android.support:support-core-utils:24.2.0"</b>
}
</pre>
</li>
</ol>
+<p class="caution">
+ <strong>Caution:</strong> Using dynamic dependencies (for example,
+ <code>palette-v7:23.0.+</code>) can cause unexpected version updates and
+ regression incompatibilities. We recommend that you explicitly specify a
+ library version (for example, <code>palette-v7:24.2.0</code>).
+</p>
+
<h2 id="using-apis">Using Support Library APIs</h2>
<p>Support Library classes that provide support for existing framework APIs typically have the
@@ -141,12 +148,12 @@
<pre>
<uses-sdk
- android:minSdkVersion="<b>7</b>"
- android:targetSdkVersion="17" />
+ android:minSdkVersion="<b>14</b>"
+ android:targetSdkVersion="23" />
</pre>
<p>The manifest setting tells Google Play that your application can be installed on devices with Android
- 2.1 (API level 7) and higher. </p>
+ 4.0 (API level 14) and higher. </p>
<p>If you are using Gradle build files, the <code>minSdkVersion</code> setting in the build file
overrides the manifest settings. </p>
@@ -158,7 +165,7 @@
...
defaultConfig {
- minSdkVersion 8
+ minSdkVersion 16
...
}
...
@@ -166,13 +173,15 @@
</pre>
<p>In this case, the build file setting tells Google Play that the default build variant of your
- application can be installed on devices with Android 2.2 (API level 8) and higher. For more
+ application can be installed on devices with Android 4.1 (API level 16) and higher. For more
information about build variants, see
<a href="{@docRoot}studio/build/index.html">Build System Overview</a>. </p>
<p class="note">
- <strong>Note:</strong> If you are including the v4 support and v7 appcompat libraries in your
- application, you should specify a minimum SDK version of <code>"7"</code> (and not
- <code>"4"</code>). The highest support library level you include in your application determines
- the lowest API version in which it can operate.
+ <strong>Note:</strong> If you are including several support libraries, the
+ minimum SDK version must be the <em>highest</em> version required by any of
+ the specified libraries. For example, if your app includes both the <a href=
+ "features.html#v14-preference">v14 Preference Support library</a> and the
+ <a href="features.html#v17-leanback">v17 Leanback library</a>, your minimum
+ SDK version must be 17 or higher.
</p>
diff --git a/docs/html/training/articles/assistant.jd b/docs/html/training/articles/assistant.jd
index a1fbd6b..703b377 100644
--- a/docs/html/training/articles/assistant.jd
+++ b/docs/html/training/articles/assistant.jd
@@ -11,110 +11,92 @@
<div id="tb">
<h2>In this document</h2>
<ol>
- <li><a href="#assist_api">Using the Assist API</a>
+ <li><a href="#assist_api">Using the Assistant</a>
<ol>
- <li><a href="#assist_api_lifecycle">Assist API Lifecycle</a></li>
- <li><a href="#source_app">Source App</a></li>
- <li><a href="#destination_app">Destination App</a></li>
+ <li><a href="#source_app">Source app</a></li>
+ <li><a href="#destination_app">Destination app</a></li>
</ol>
</li>
- <li><a href="#implementing_your_own_assistant">Implementing your
- own assistant</a></li>
+ <li><a href="#implementing_your_own_assistant">Implementing Your
+ Own Assistant</a></li>
</ol>
</div>
</div>
<p>
Android 6.0 Marshmallow introduces a new way for users to engage with apps
- through the assistant.
+ through the assistant. The assistant is a top-level window that users can view to obtain
+ contextually relevant actions for the current activity. These actions might include deep links
+ to other apps on the device.</p>
+
+<p>
+ Users activate the assistant with a long press on the Home button or by saying a
+ <a href="{@docRoot}reference/android/service/voice/AlwaysOnHotwordDetector.html">keyphrase</a>.
+ In response, the system opens a top-level window that displays contextually
+ relevant actions.
</p>
<p>
- Users summon the assistant with a long-press on the Home button or by saying
- the {@link android.service.voice.AlwaysOnHotwordDetector keyphrase}. In
- response to the long-press, the system opens a top-level window that displays
- contextually relevant actions for the current activity. These potential
- actions might include deep links to other apps on the device.
+ Google App implements the assistant overlay window through a feature called
+ Now on Tap, which works with the Android platform-level functionality. The system allows
+ the user to select an assistant app, which obtains contextual information from your app
+ using Android’s Assist API.
</p>
+<p>
+ This guide explains how Android apps use Android's Assist API to improve the assistant
+ user experience.
+<p/>
+</p>
+
+
+<h2 id="assist_api">Using the Assistant</h2>
<p>
- This guide explains how Android apps use Android's Assist API to improve the
- assistant user experience.
+ Figure 1 illustrates a typical user interaction with the assistant. When the user long-presses
+ the Home button, the Assist API callbacks are invoked
+ in the <em>source</em> app (step 1). The assistant renders the overlay window (steps 2 and 3),
+ and then the user selects the action to perform. The assistant executes the selected action,
+ such as firing an intent with a deep link to the (<em>destination</em>) restaurant app (step 4).
</p>
-
-<h2 id="assist_api">Using the Assist API</h2>
-
-<p>
- The example below shows how Google Now integrates with the Android assistant
- using a feature called Now on Tap.
-</p>
-
-<p>
- The assistant overlay window in our example (2, 3) is implemented by Google
- Now through a feature called Now on Tap, which works in concert with the
- Android platform-level functionality. The system allows the user to select
- the assistant app (Figure 2) that obtains contextual information from the
- <em>source</em> app using the Assist API which is a part of the platform.
-</p>
-
-
<div>
<img src="{@docRoot}images/training/assistant/image01.png">
<p class="img-caption" style="text-align:center;">
Figure 1. Assistant interaction example with the Now on Tap feature of
- Google Now
+ the Google App
</p>
</div>
<p>
- An Android user first configures the assistant and can change system options
- such as using text and view hierarchy as well as the screenshot of the
- current screen (Figure 2).
+ Users can configure the assistant by selecting <strong>Settings > Apps > Default Apps >
+ Assist & voice input</strong>. Users can change system options such as accessing
+ the screen contents as text and accessing a screenshot, as shown in Figure 2.
</p>
-<p>
- From there, the assistant receives the information only when the user
- activates assistance, such as when they tap and hold the Home button ( shown
- in Figure 1, step 1).
-</p>
-
-<div style="float:right;margin:1em;max-width:300px">
+<div id="assist-input-settings" style="float:right;margin:1em;max-width:300px">
<img src="{@docRoot}images/training/assistant/image02.png">
<p class="img-caption" style="text-align:center;">
- Figure 2. Assist & voice input settings (<em>Settings/Apps/Default
- Apps/Assist & voice input</em>)
+ Figure 2. Assist & voice input settings
</p>
</div>
-<h3 id="assist_api_lifecycle">Assist API Lifecycle</h3>
+<h3 id="source_app">Source app</h3>
<p>
- Going back to our example from Figure 1, the Assist API callbacks are invoked
- in the <em>source</em> app after step 1 (user long-presses the Home button)
- and before step 2 (the assistant renders the overlay window). Once the user
- selects the action to perform (step 3), the assistant executes it, for
- example by firing an intent with a deep link to the (<em>destination</em>)
- restaurant app (step 4).
-</p>
-
-<h3 id="source_app">Source App</h3>
-
-<p>
- In most cases, your app does not need to do anything extra to integrate with
- the assistant if you already follow <a href=
+ To ensure that your app works with the assistant as a source of information for the user,
+ you need only follow <a href=
"{@docRoot}guide/topics/ui/accessibility/apps.html">accessibility best
practices</a>. This section describes how to provide additional information
- to help improve the assistant user experience, as well as scenarios, such as
- custom Views, that need special handling.
+ to help improve the assistant user experience as well as scenarios
+ that need special handling, such as custom Views.
</p>
-
-<h4 id="share_additional_information_with_the_assistant">Share Additional Information with the Assistant</h4>
+<h4 id="share_additional_information_with_the_assistant">Share additional information
+ with the assistant</h4>
<p>
In addition to the text and the screenshot, your app can share
- <em>additional</em> information with the assistant. For example, your music
- app can choose to pass current album information, so that the assistant can
+ other information with the assistant. For example, your music
+ app can choose to pass current album information so that the assistant can
suggest smarter actions tailored to the current activity.
</p>
@@ -122,13 +104,13 @@
To provide additional information to the assistant, your app provides
<em>global application context</em> by registering an app listener and
supplies activity-specific information with activity callbacks as shown in
- Figure 3.
+ Figure 3:
</p>
<div>
<img src="{@docRoot}images/training/assistant/image03.png">
<p class="img-caption" style="text-align:center;">
- Figure 3. Assist API lifecycle sequence diagram.
+ Figure 3. Assist API lifecycle sequence diagram
</p>
</div>
@@ -136,43 +118,42 @@
To provide global application context, the app creates an implementation of
{@link android.app.Application.OnProvideAssistDataListener} and registers it
using {@link
- android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener)}.
- In order to provide activity-specific contextual information, activity
- overrides {@link android.app.Activity#onProvideAssistData(android.os.Bundle)}
+ android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.
+ To provide activity-specific contextual information, the activity
+ overrides {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
and {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}.
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}.
The two activity methods are called <em>after</em> the optional global
- callback (registered with {@link
- android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener)})
- is invoked. Since the callbacks execute on the main thread, they should
+ callback is invoked. Because the callbacks execute on the main thread, they should
complete <a href="{@docRoot}training/articles/perf-anr.html">promptly</a>.
The callbacks are invoked only when the activity is <a href=
"{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">running</a>.
</p>
-<h5 id="providing_context">Providing Context</h5>
+<h5 id="providing_context">Providing context</h5>
<p>
- {@link android.app.Activity#onProvideAssistData(android.os.Bundle)} is called
- when the user is requesting the assistant to build a full {@link
+ When the user activates the assistant,
+ {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} is called to build a full
+ {@link
android.content.Intent#ACTION_ASSIST} Intent with all of the context of the
current application represented as an instance of the {@link
android.app.assist.AssistStructure}. You can override this method to place
- into the bundle anything you would like to appear in the
- <code>EXTRA_ASSIST_CONTEXT</code> part of the assist Intent.
+ anything you like into the bundle to appear in the
+ {@link android.content.Intent#EXTRA_ASSIST_CONTEXT} part of the assist intent.
</p>
-<h5 id="describing_content">Describing Content</h5>
+<h5 id="describing_content">Describing content</h5>
<p>
Your app can implement {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}
- to improve assistant user experience by providing references to content
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
+ to improve the assistant user experience by providing content-related references
related to the current activity. You can describe the app content using the
- common vocabulary defined by <a href="https://schema.org">Schema.org</a>
+ common vocabulary defined by <a href="https://schema.org" class="external-link">Schema.org</a>
through a JSON-LD object. In the example below, a music app provides
- structured data to describe the music album the user is currently
- looking at.
+ structured data to describe the music album that the user is currently
+ viewing:
</p>
<pre class="prettyprint">
@@ -191,127 +172,158 @@
</pre>
<p>
- Custom implementations of {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}
- may also adjust the provided {@link
- android.app.assist.AssistContent#setIntent(android.content.Intent) content
- intent} to better reflect the top-level context of the activity, supply
- {@link android.app.assist.AssistContent#setWebUri(android.net.Uri) the URI}
- of the displayed content, and fill in its {@link
- android.app.assist.AssistContent#setClipData(android.content.ClipData)} with
- additional content of interest that the user is currently viewing.
+ You can also improve the user experience with custom implementations of
+ {@link
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()},
+ which can provide the following benefits:
+</p>
+<ul>
+ <li><a href="{@docRoot}reference/android/app/assist/AssistContent.html#setIntent(android.content.Intent)">
+ Adjusts the provided content
+ intent</a> to
+ better reflect the top-level context of the activity.</li>
+ <li><a href="{@docRoot}reference/android/app/assist/AssistContent.html#setWebUri(android.net.Uri)">
+ Supplies the URI</a>
+ of the displayed content.</li>
+ <li>Fills in {@link
+ android.app.assist.AssistContent#setClipData(android.content.ClipData) setClipData()} with additional
+ content of interest that the user is currently viewing.</li>
+</ul>
+<p class="note">
+ <strong>Note: </strong>Apps that use a custom text selection implementation likely need
+ to implement {@link
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
+ and call {@link android.app.assist.AssistContent#setClipData(android.content.ClipData) setClipData()}.
</p>
-<h4 id="default_implementation">Default Implementation</h4>
+<h4 id="default_implementation">Default implementation</h4>
<p>
- If neither {@link
- android.app.Activity#onProvideAssistData(android.os.Bundle)} nor {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}
- callbacks are implemented, the system will still proceed and pass the
- information collected automatically to the assistant unless the current
+ If neither the {@link
+ android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} nor the {@link
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
+ callback is implemented, the system still proceeds and passes the
+ automatically collected information to the assistant unless the current
window is flagged as <a href="#excluding_views">secure</a>.
As shown in Figure 3, the system uses the default implementations of {@link
- android.view.View#onProvideStructure(android.view.ViewStructure)} and {@link
- android.view.View#onProvideVirtualStructure(android.view.ViewStructure)} to
+ android.view.View#onProvideStructure(android.view.ViewStructure) onProvideStructure()} and {@link
+ android.view.View#onProvideVirtualStructure(android.view.ViewStructure) onProvideVirtualStructure()} to
collect text and view hierarchy information. If your view implements custom
- text drawing, you should override {@link
- android.view.View#onProvideStructure(android.view.ViewStructure)} to provide
+ text drawing, override {@link
+ android.view.View#onProvideStructure(android.view.ViewStructure) onProvideStructure()} to provide
the assistant with the text shown to the user by calling {@link
- android.view.ViewStructure#setText(java.lang.CharSequence)}.
+ android.view.ViewStructure#setText(java.lang.CharSequence) setText(CharSequence)}.
</p>
<p>
- <strong>In most cases, implementing accessibility support will enable the
- assistant to obtain the information it needs.</strong> This includes
- providing {@link android.R.attr#contentDescription
- android:contentDescription} attributes, populating {@link
- android.view.accessibility.AccessibilityNodeInfo} for custom views, making
- sure custom {@link android.view.ViewGroup ViewGroups} correctly {@link
- android.view.ViewGroup#getChildAt(int) expose} their children, and following
- the best practices described in <a href=
- "{@docRoot}guide/topics/ui/accessibility/apps.html">“Making Applications
- Accessible”</a>.
-</p>
+ <em>In most cases, implementing accessibility support enables the
+ assistant to obtain the information it needs.</em> To implement accessibility support,
+ observe the best practices described in <a href=
+ "{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications
+ Accessible</a>, including the following:</p>
+
+<ul>
+ <li>Provide {@link android.R.attr#contentDescription
+ android:contentDescription} attributes.</li>
+ <li>Populate {@link
+ android.view.accessibility.AccessibilityNodeInfo} for custom views.</li>
+ <li>Make
+ sure that custom {@link android.view.ViewGroup ViewGroup} objects correctly
+ <a href="{@docRoot}reference/android/view/ViewGroup.html#getChildAt(int)">expose</a>
+ their children.</li>
+</ul>
<h4 id="excluding_views">Excluding views from the assistant</h4>
<p>
- An activity can exclude the current view from the assistant. This is accomplished
+ To handle sensitive information, your app can exclude the current view from the assistant
by setting the {@link android.view.WindowManager.LayoutParams#FLAG_SECURE
- FLAG_SECURE} layout parameter of the WindowManager and must be done
- explicitly for every window created by the activity, including Dialogs. Your
- app can also use {@link android.view.SurfaceView#setSecure(boolean)
- SurfaceView.setSecure} to exclude a surface from the assistant. There is no
+ FLAG_SECURE} layout parameter of the {@link android.view.WindowManager}. You must set {@link
+ android.view.WindowManager.LayoutParams#FLAG_SECURE
+ FLAG_SECURE} explicitly for
+ every window created by the activity, including dialogs. Your app can also use
+ {@link android.view.SurfaceView#setSecure(boolean) setSecure()} to exclude
+ a surface from the assistant. There is no
global (app-level) mechanism to exclude all views from the assistant. Note
- that <code>FLAG_SECURE</code> does not cause the Assist API callbacks to stop
- firing. The activity which uses <code>FLAG_SECURE</code> can still explicitly
+ that {@link android.view.WindowManager.LayoutParams#FLAG_SECURE
+ FLAG_SECURE} does not cause the Assist API callbacks to stop
+ firing. The activity that uses {@link android.view.WindowManager.LayoutParams#FLAG_SECURE
+ FLAG_SECURE} can still explicitly
provide information to the assistant using the callbacks described earlier
this guide.
</p>
-<h4 id="voice_interactions">Voice Interactions</h4>
+<p class="note"><strong>Note: </strong>For enterprise accounts (Android for Work),
+ the administrator can disable
+ the collection of assistant data for the work profile by using the {@link
+ android.app.admin.DevicePolicyManager#setScreenCaptureDisabled(android.content.ComponentName, boolean)
+ setScreenCaptureDisabled()} method of the {@link android.app.admin.DevicePolicyManager} API.</p>
+
+<h4 id="voice_interactions">Voice interactions</h4>
<p>
- Assist API callbacks are also invoked upon {@link
- android.service.voice.AlwaysOnHotwordDetector keyphrase detection}. For more
- information see the <a href="https://developers.google.com/voice-actions/">voice
- actions</a> documentation.
+ Assist API callbacks are also invoked upon
+ <a href="{@docRoot}reference/android/service/voice/AlwaysOnHotwordDetector.html">keyphrase
+ detection</a>. For more information, see the
+ <a href="https://developers.google.com/voice-actions/" class="external-link">Voice
+ Actions</a> documentation.
</p>
<h4 id="z-order_considerations">Z-order considerations</h4>
<p>
The assistant uses a lightweight overlay window displayed on top of the
- current activity. The assistant can be summoned by the user at any time.
- Therefore, apps should not create permanent {@link
- android.Manifest.permission#SYSTEM_ALERT_WINDOW system alert}
- windows interfering with the overlay window shown in Figure 4.
+ current activity. Because the user can activate the assistant at any time,
+ don't create permanent <a
+ href="{@docRoot}reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW">
+ system alert</a> windows that interfere with the overlay window, as shown in
+ Figure 4.
</p>
<div style="">
<img src="{@docRoot}images/training/assistant/image04.png">
<p class="img-caption" style="text-align:center;">
- Figure 4. Assist layer Z-order.
+ Figure 4. Assist layer Z-order
</p>
</div>
<p>
- If your app uses {@link
- android.Manifest.permission#SYSTEM_ALERT_WINDOW system alert} windows, it
- must promptly remove them as leaving them on the screen will degrade user
- experience and annoy the users.
+ If your app uses <a
+ href="{@docRoot}reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW">
+ system alert</a> windows, remove them promptly because leaving them on the
+ screen degrades the user experience.
</p>
-<h3 id="destination_app">Destination App</h3>
+<h3 id="destination_app">Destination app</h3>
<p>
- The matching between the current user context and potential actions displayed
- in the overlay window (shown in step 3 in Figure 1) is specific to the
- assistant’s implementation. However, consider adding <a href=
- "{@docRoot}training/app-indexing/deep-linking.html">deep linking</a> support
- to your app. The assistant will typically take advantage of deep linking. For
- example, Google Now uses deep linking and <a href=
- "https://developers.google.com/app-indexing/">App Indexing</a> in order to
+ The assistant typically takes advantage of deep linking to find destination apps. To make your
+ app a potential destination app, consider adding <a href=
+ "{@docRoot}training/app-indexing/deep-linking.html">deep linking</a> support. The matching
+ between the current user context and deep links or other potential actions displayed in the
+ overlay window (shown in step 3 in Figure 1) is specific to the assistant’s implementation.
+ For
+ example, the Google App uses deep linking and <a href=
+ "https://developers.google.com/app-indexing/" class="external-link">Firebase App Indexing</a> in order to
drive traffic to destination apps.
</p>
-<h2 id="implementing_your_own_assistant">Implementing your own assistant </h2>
+<h2 id="implementing_your_own_assistant">Implementing Your Own Assistant </h2>
<p>
- Some developers may wish to implement their own assistant. As shown in Figure
- 2, the active assistant app can be selected by the Android user. The
+ You may wish to implement your own assistant. As shown in <a href="#assist-input-settings">Figure
+ 2</a>, the user can select the active assistant app. The
assistant app must provide an implementation of {@link
android.service.voice.VoiceInteractionSessionService} and {@link
android.service.voice.VoiceInteractionSession} as shown in <a href=
- "https://android.googlesource.com/platform/frameworks/base/+/android-5.0.1_r1/tests/VoiceInteraction?autodive=0%2F%2F%2F%2F%2F%2F">
- this</a> example and it requires the {@link
- android.Manifest.permission#BIND_VOICE_INTERACTION} permission. It can then
+ "https://android.googlesource.com/platform/frameworks/base/+/marshmallow-release/tests/VoiceInteraction/" class="external-link">
+ this <code>VoiceInteraction</code> example</a>. It also requires the {@link
+ android.Manifest.permission#BIND_VOICE_INTERACTION} permission. The assistant can then
receive the text and view hierarchy represented as an instance of the {@link
android.app.assist.AssistStructure} in {@link
android.service.voice.VoiceInteractionSession#onHandleAssist(android.os.Bundle,
android.app.assist.AssistStructure,android.app.assist.AssistContent) onHandleAssist()}.
- The assistant receives the screenshot through {@link
+ It receives the screenshot through {@link
android.service.voice.VoiceInteractionSession#onHandleScreenshot(android.graphics.Bitmap)
onHandleScreenshot()}.
</p>
diff --git a/docs/html/training/implementing-navigation/nav-drawer.jd b/docs/html/training/implementing-navigation/nav-drawer.jd
index d359a47..abc79b6 100644
--- a/docs/html/training/implementing-navigation/nav-drawer.jd
+++ b/docs/html/training/implementing-navigation/nav-drawer.jd
@@ -173,7 +173,7 @@
<pre>
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
diff --git a/docs/html/training/notify-user/navigation.jd b/docs/html/training/notify-user/navigation.jd
index 65f8d48b..d0ec1cd 100644
--- a/docs/html/training/notify-user/navigation.jd
+++ b/docs/html/training/notify-user/navigation.jd
@@ -205,7 +205,7 @@
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
-PendingIntent notifyIntent =
+PendingIntent pendingIntent =
PendingIntent.getActivity(
this,
0,
@@ -214,7 +214,7 @@
);
// Puts the PendingIntent into the notification builder
-builder.setContentIntent(notifyIntent);
+builder.setContentIntent(pendingIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
diff --git a/docs/html/training/testing/unit-testing/local-unit-tests.jd b/docs/html/training/testing/unit-testing/local-unit-tests.jd
index 8b109ee..d19de4f 100644
--- a/docs/html/training/testing/unit-testing/local-unit-tests.jd
+++ b/docs/html/training/testing/unit-testing/local-unit-tests.jd
@@ -112,12 +112,16 @@
returned result against the expected result.</p>
<h3 id="mocking-dependencies">Mock Android dependencies</h3>
-<p>
-By default, the <a href="{@docRoot}tools/building/plugin-for-gradle.html">
-Android Plug-in for Gradle</a> executes your local unit tests against a modified
-version of the {@code android.jar} library, which does not contain any actual code. Instead, method
-calls to Android classes from your unit test throw an exception.
-</p>
+
+<p>By default, the <a href=
+"{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for
+Gradle</a> executes your local unit tests against a modified version of the
+{@code android.jar} library, which does not contain any actual code. Instead,
+method calls to Android classes from your unit test throw an exception. This is
+to make sure you test only your code and do not depend on any
+particular behavior of the Android platform (that you have not explicitly
+mocked).</p>
+
<p>
You can use a mocking framework to stub out external dependencies in your code, to easily test that
your component interacts with a dependency in an expected way. By substituting Android dependencies
@@ -195,6 +199,26 @@
class="external-link">sample code</a>.
</p>
+<p>If the exceptions thrown by Android APIs in the
+<code>android.jar</code> are problematic for your tests, you can change the behavior so that methods
+instead return either null or zero by adding the following configuration in your project's
+top-level <code>build.gradle</code> file:</p>
+
+<pre>
+android {
+ ...
+ testOptions {
+ unitTests.returnDefaultValues = true
+ }
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong>
+Setting the <code>returnDefaultValues</code> property to <code>true</code>
+should be done with care. The null/zero return values can introduce
+regressions in your tests, which are hard to debug and might allow failing tests
+to pass. Only use it as a last resort.</p>
+
<h2 id="run">Run Local Unit Tests</h2>
diff --git a/docs/html/training/transitions/index.jd b/docs/html/training/transitions/index.jd
index 53faa01..b8f99c8 100644
--- a/docs/html/training/transitions/index.jd
+++ b/docs/html/training/transitions/index.jd
@@ -48,11 +48,9 @@
animations.</p>
<p class="note"><strong>Note:</strong> For Android versions earlier than 4.4.2 (API level 19)
-but greater than or equal to Android 4.0 (API level 14), use the <code>animateLayoutChanges</code>
-attribute to animate layouts. To learn more, see
-<a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a> and
-<a href="{@docRoot}training/animation/layout.html">Animating Layout Changes</a>.</p>
-
+but greater than or equal to Android 4.0 (API level 14), use the Android Support
+Library's <a href="/reference/android/support/transitions/package-summary.html"
+><code>android.support.transition</code></a> package.</p>
<h2>Lessons</h2>
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index cbef540..ed40b77 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -571,13 +571,12 @@
*
* <p>If this method returns {@code null}, and the spec is used to generate an asymmetric (RSA
* or EC) key pair, the public key will have a self-signed certificate if it has purpose {@link
- * KeyProperties#PURPOSE_SIGN} (see {@link #KeyGenParameterSpec(String, int)). If does not have
- * purpose {@link KeyProperties#PURPOSE_SIGN}, it will have a fake certificate.
+ * KeyProperties#PURPOSE_SIGN}. If does not have purpose {@link KeyProperties#PURPOSE_SIGN}, it
+ * will have a fake certificate.
*
* <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a
- * {@link KeyGenParameterSpec} with {@link #hasAttestationCertificate()} returning
- * non-{@code null} is used to generate a symmetric (AES or HMAC) key,
- * {@link KeyGenerator#generateKey())} will throw
+ * KeyGenParameterSpec with getAttestationChallenge returning non-null is used to generate a
+ * symmetric (AES or HMAC) key, {@link javax.crypto.KeyGenerator#generateKey()} will throw
* {@link java.security.InvalidAlgorithmParameterException}.
*
* @see Builder#setAttestationChallenge(byte[])
@@ -1050,11 +1049,6 @@
return this;
}
- /*
- * TODO(swillden): Update this documentation to describe the hardware and software root
- * keys, including information about CRL/OCSP services for discovering revocations, and to
- * link to documentation of the extension format and content.
- */
/**
* Sets whether an attestation certificate will be generated for this key pair, and what
* challenge value will be placed in the certificate. The attestation certificate chain
@@ -1074,17 +1068,15 @@
*
* <p>If {@code attestationChallenge} is {@code null}, and this spec is used to generate an
* asymmetric (RSA or EC) key pair, the public key certificate will be self-signed if the
- * key has purpose {@link KeyProperties#PURPOSE_SIGN} (see
- * {@link #KeyGenParameterSpec(String, int)). If the key does not have purpose
- * {@link KeyProperties#PURPOSE_SIGN}, it is not possible to use the key to sign a
- * certificate, so the public key certificate will contain a dummy signature.
+ * key has purpose {@link android.security.keystore.KeyProperties#PURPOSE_SIGN}. If the key
+ * does not have purpose {@link android.security.keystore.KeyProperties#PURPOSE_SIGN}, it is
+ * not possible to use the key to sign a certificate, so the public key certificate will
+ * contain a dummy signature.
*
* <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a
- * {@code getAttestationChallenge} returns non-{@code null} and the spec is used to
- * generate a symmetric (AES or HMAC) key, {@link KeyGenerator#generateKey()} will throw
+ * {@link #getAttestationChallenge()} returns non-null and the spec is used to generate a
+ * symmetric (AES or HMAC) key, {@link javax.crypto.KeyGenerator#generateKey()} will throw
* {@link java.security.InvalidAlgorithmParameterException}.
- *
- * @see Builder#setAttestationChallenge(String attestationChallenge)
*/
@NonNull
public Builder setAttestationChallenge(byte[] attestationChallenge) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 60d3339..f039e1e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -21,6 +21,7 @@
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.GestureDescription;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
@@ -2755,7 +2756,7 @@
}
@Override
- public void sendMotionEvents(int sequence, ParceledListSlice events) {
+ public void sendGesture(int sequence, ParceledListSlice gestureSteps) {
synchronized (mLock) {
if (mSecurityPolicy.canPerformGestures(this)) {
final long endMillis =
@@ -2769,9 +2770,16 @@
}
}
if (mMotionEventInjector != null) {
- mMotionEventInjector.injectEvents((List<MotionEvent>) events.getList(),
- mServiceInterface, sequence);
- return;
+ List<GestureDescription.GestureStep> steps = gestureSteps.getList();
+ List<MotionEvent> events = GestureDescription.MotionEventGenerator
+ .getMotionEventsFromGestureSteps(steps);
+ // Confirm that the motion events end with an UP event.
+ if (events.get(events.size() - 1).getAction() == MotionEvent.ACTION_UP) {
+ mMotionEventInjector.injectEvents(events, mServiceInterface, sequence);
+ return;
+ } else {
+ Slog.e(LOG_TAG, "Gesture is not well-formed");
+ }
} else {
Slog.e(LOG_TAG, "MotionEventInjector installation timed out");
}
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index d64fe32..42e75c6 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -1215,6 +1215,9 @@
private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
+ if (TextUtils.isEmpty(pattern)) {
+ throw new IllegalArgumentException("Pattern can't be null or empty");
+ }
CredentialHash storedHash = mStorage.readPatternHash(userId);
return doVerifyPattern(pattern, storedHash, hasChallenge, challenge, userId);
}
@@ -1306,6 +1309,9 @@
private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
+ if (TextUtils.isEmpty(password)) {
+ throw new IllegalArgumentException("Password can't be null or empty");
+ }
CredentialHash storedHash = mStorage.readPasswordHash(userId);
return doVerifyPassword(password, storedHash, hasChallenge, challenge, userId);
}