Merge "Notification listener backup & restore"
diff --git a/Android.mk b/Android.mk
index 452d72c..84cad4e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -559,6 +559,7 @@
 	frameworks/base/core/java/android/app/PendingIntent.aidl \
 	frameworks/base/core/java/android/app/AlarmManager.aidl \
 	frameworks/base/core/java/android/app/SearchableInfo.aidl \
+	frameworks/base/core/java/android/app/VoiceInteractor.aidl \
 	frameworks/base/core/java/android/app/job/JobParameters.aidl \
 	frameworks/base/core/java/android/app/job/JobInfo.aidl \
 	frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
diff --git a/api/current.txt b/api/current.txt
index c05254a..7bac613 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5355,8 +5355,25 @@
     method public void onConfirmationResult(boolean, android.os.Bundle);
   }
 
+  public static class VoiceInteractor.PickOptionRequest extends android.app.VoiceInteractor.Request {
+    ctor public VoiceInteractor.PickOptionRequest(java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
+    method public void onPickOptionResult(boolean, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
+  }
+
+  public static final class VoiceInteractor.PickOptionRequest.Option implements android.os.Parcelable {
+    ctor public VoiceInteractor.PickOptionRequest.Option(java.lang.CharSequence);
+    method public android.app.VoiceInteractor.PickOptionRequest.Option addSynonym(java.lang.CharSequence);
+    method public int countSynonyms();
+    method public int describeContents();
+    method public android.os.Bundle getExtras();
+    method public java.lang.CharSequence getLabel();
+    method public java.lang.CharSequence getSynonymAt(int);
+    method public void setExtras(android.os.Bundle);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.VoiceInteractor.PickOptionRequest.Option> CREATOR;
+  }
+
   public static abstract class VoiceInteractor.Request {
-    ctor public VoiceInteractor.Request();
     method public void cancel();
     method public android.app.Activity getActivity();
     method public android.content.Context getContext();
@@ -17315,6 +17332,7 @@
     method public int describeContents();
     method public final int getAudioChannelCount();
     method public final int getAudioSampleRate();
+    method public final java.lang.String getDescription();
     method public final android.os.Bundle getExtra();
     method public final java.lang.String getId();
     method public final java.lang.String getLanguage();
@@ -17334,6 +17352,7 @@
     method public android.media.tv.TvTrackInfo build();
     method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
     method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
+    method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.String);
     method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
     method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
     method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
@@ -27895,10 +27914,12 @@
     method public boolean onKeyLongPress(int, android.view.KeyEvent);
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public abstract void onPickOption(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
     method public void onShow(android.os.Bundle, int);
     method public void onTaskFinished(android.content.Intent, int);
     method public void onTaskStarted(android.content.Intent, int);
     method public void setContentView(android.view.View);
+    method public void setKeepAwake(boolean);
     method public void setTheme(int);
     method public void show();
     method public void showWindow();
@@ -27924,6 +27945,7 @@
     method public void sendCommandResult(boolean, android.os.Bundle);
     method public void sendCompleteVoiceResult(android.os.Bundle);
     method public void sendConfirmResult(boolean, android.os.Bundle);
+    method public void sendPickOptionResult(boolean, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
   }
 
   public abstract class VoiceInteractionSessionService extends android.app.Service {
diff --git a/api/system-current.txt b/api/system-current.txt
index 5388207..89c0460e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5445,8 +5445,25 @@
     method public void onConfirmationResult(boolean, android.os.Bundle);
   }
 
+  public static class VoiceInteractor.PickOptionRequest extends android.app.VoiceInteractor.Request {
+    ctor public VoiceInteractor.PickOptionRequest(java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
+    method public void onPickOptionResult(boolean, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
+  }
+
+  public static final class VoiceInteractor.PickOptionRequest.Option implements android.os.Parcelable {
+    ctor public VoiceInteractor.PickOptionRequest.Option(java.lang.CharSequence);
+    method public android.app.VoiceInteractor.PickOptionRequest.Option addSynonym(java.lang.CharSequence);
+    method public int countSynonyms();
+    method public int describeContents();
+    method public android.os.Bundle getExtras();
+    method public java.lang.CharSequence getLabel();
+    method public java.lang.CharSequence getSynonymAt(int);
+    method public void setExtras(android.os.Bundle);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.VoiceInteractor.PickOptionRequest.Option> CREATOR;
+  }
+
   public static abstract class VoiceInteractor.Request {
-    ctor public VoiceInteractor.Request();
     method public void cancel();
     method public android.app.Activity getActivity();
     method public android.content.Context getContext();
@@ -18734,6 +18751,7 @@
     method public int describeContents();
     method public final int getAudioChannelCount();
     method public final int getAudioSampleRate();
+    method public final java.lang.String getDescription();
     method public final android.os.Bundle getExtra();
     method public final java.lang.String getId();
     method public final java.lang.String getLanguage();
@@ -18753,6 +18771,7 @@
     method public android.media.tv.TvTrackInfo build();
     method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
     method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
+    method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.String);
     method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
     method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
     method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
@@ -29779,10 +29798,12 @@
     method public boolean onKeyLongPress(int, android.view.KeyEvent);
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public abstract void onPickOption(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
     method public void onShow(android.os.Bundle, int);
     method public void onTaskFinished(android.content.Intent, int);
     method public void onTaskStarted(android.content.Intent, int);
     method public void setContentView(android.view.View);
+    method public void setKeepAwake(boolean);
     method public void setTheme(int);
     method public void show();
     method public void showWindow();
@@ -29808,6 +29829,7 @@
     method public void sendCommandResult(boolean, android.os.Bundle);
     method public void sendCompleteVoiceResult(android.os.Bundle);
     method public void sendConfirmResult(boolean, android.os.Bundle);
+    method public void sendPickOptionResult(boolean, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
   }
 
   public abstract class VoiceInteractionSessionService extends android.app.Service {
diff --git a/core/java/android/annotation/TransitionRes.java b/core/java/android/annotation/TransitionRes.java
new file mode 100644
index 0000000..06bac74
--- /dev/null
+++ b/core/java/android/annotation/TransitionRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a transition resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface TransitionRes {
+}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 997f69d..1484af8 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2440,6 +2440,16 @@
             reply.writeNoException();
             return true;
         }
+
+        case SET_VOICE_KEEP_AWAKE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
+                    data.readStrongBinder());
+            boolean keepAwake = data.readInt() != 0;
+            setVoiceKeepAwake(session, keepAwake);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -5658,5 +5668,19 @@
         reply.recycle();
     }
 
+    @Override
+    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(session.asBinder());
+        data.writeInt(keepAwake ? 1 : 0);
+        mRemote.transact(SET_VOICE_KEEP_AWAKE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 3dcbdd2..d794aa3 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -485,6 +485,9 @@
     public void setDumpHeapDebugLimit(String processName, long maxMemSize) throws RemoteException;
     public void dumpHeapFinished(String path) throws RemoteException;
 
+    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
+            throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -818,4 +821,5 @@
     int GET_LOCK_TASK_MODE_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+286;
     int SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+287;
     int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288;
+    int SET_VOICE_KEEP_AWAKE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+289;
 }
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 8abe223..79797c9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -27,6 +27,7 @@
 import android.hardware.display.DisplayManagerGlobal;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.view.Display;
@@ -164,7 +165,7 @@
 
             WeakReference<Resources> wr = mActiveResources.get(key);
             r = wr != null ? wr.get() : null;
-            //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
+            //if (r != null) Log.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
             if (r != null && r.getAssets().isUpToDate()) {
                 if (DEBUG) Slog.w(TAG, "Returning cached resources " + r + " " + resDir
                         + ": appScale=" + r.getCompatibilityInfo().applicationScale
@@ -174,7 +175,7 @@
         }
 
         //if (r != null) {
-        //    Slog.w(TAG, "Throwing away out-of-date resources!!!! "
+        //    Log.w(TAG, "Throwing away out-of-date resources!!!! "
         //            + r + " " + resDir);
         //}
 
@@ -204,14 +205,18 @@
 
         if (libDirs != null) {
             for (String libDir : libDirs) {
-                if (assets.addAssetPath(libDir) == 0) {
-                    Slog.w(TAG, "Asset path '" + libDir +
-                            "' does not exist or contains no resources.");
+                if (libDir.endsWith(".apk")) {
+                    // Avoid opening files we know do not have resources,
+                    // like code-only .jar files.
+                    if (assets.addAssetPath(libDir) == 0) {
+                        Log.w(TAG, "Asset path '" + libDir +
+                                "' does not exist or contains no resources.");
+                    }
                 }
             }
         }
 
-        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
+        //Log.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
         DisplayMetrics dm = getDisplayMetricsLocked(displayId);
         Configuration config;
         final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
diff --git a/core/java/android/app/VoiceInteractor.aidl b/core/java/android/app/VoiceInteractor.aidl
new file mode 100644
index 0000000..40a4a0e
--- /dev/null
+++ b/core/java/android/app/VoiceInteractor.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+parcelable VoiceInteractor.PickOptionRequest.Option;
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 7b84cb4..da7bb05 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -21,6 +21,8 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -69,6 +71,7 @@
         public void executeMessage(Message msg) {
             SomeArgs args = (SomeArgs)msg.obj;
             Request request;
+            boolean complete;
             switch (msg.what) {
                 case MSG_CONFIRMATION_RESULT:
                     request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
@@ -81,13 +84,28 @@
                         request.clear();
                     }
                     break;
+                case MSG_PICK_OPTION_RESULT:
+                    complete = msg.arg1 != 0;
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, complete);
+                    if (DEBUG) Log.d(TAG, "onPickOptionResult: req="
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+                            + " finished=" + complete + " selection=" + args.arg2
+                            + " result=" + args.arg3);
+                    if (request != null) {
+                        ((PickOptionRequest)request).onPickOptionResult(complete,
+                                (PickOptionRequest.Option[]) args.arg2, (Bundle) args.arg3);
+                        if (complete) {
+                            request.clear();
+                        }
+                    }
+                    break;
                 case MSG_COMPLETE_VOICE_RESULT:
                     request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                     if (DEBUG) Log.d(TAG, "onCompleteVoice: req="
                             + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                             + " result=" + args.arg1);
                     if (request != null) {
-                        ((CompleteVoiceRequest)request).onCompleteResult((Bundle) args.arg2);
+                        ((CompleteVoiceRequest)request).onCompleteResult((Bundle) args.arg1);
                         request.clear();
                     }
                     break;
@@ -95,21 +113,22 @@
                     request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                     if (DEBUG) Log.d(TAG, "onAbortVoice: req="
                             + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
-                            + " result=" + args.arg1);
+                            + " result=" + args.arg2);
                     if (request != null) {
                         ((AbortVoiceRequest)request).onAbortResult((Bundle) args.arg2);
                         request.clear();
                     }
                     break;
                 case MSG_COMMAND_RESULT:
-                    request = pullRequest((IVoiceInteractorRequest)args.arg1, msg.arg1 != 0);
+                    complete = msg.arg1 != 0;
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, complete);
                     if (DEBUG) Log.d(TAG, "onCommandResult: req="
                             + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                             + " completed=" + msg.arg1 + " result=" + args.arg2);
                     if (request != null) {
                         ((CommandRequest)request).onCommandResult(msg.arg1 != 0,
                                 (Bundle) args.arg2);
-                        if (msg.arg1 != 0) {
+                        if (complete) {
                             request.clear();
                         }
                     }
@@ -129,10 +148,17 @@
 
     final IVoiceInteractorCallback.Stub mCallback = new IVoiceInteractorCallback.Stub() {
         @Override
-        public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
+        public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean finished,
                 Bundle result) {
             mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
-                    MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, request, result));
+                    MSG_CONFIRMATION_RESULT, finished ? 1 : 0, request, result));
+        }
+
+        @Override
+        public void deliverPickOptionResult(IVoiceInteractorRequest request,
+                boolean finished, PickOptionRequest.Option[] options, Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOOO(
+                    MSG_PICK_OPTION_RESULT, finished ? 1 : 0, request, options, result));
         }
 
         @Override
@@ -164,17 +190,22 @@
     final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
 
     static final int MSG_CONFIRMATION_RESULT = 1;
-    static final int MSG_COMPLETE_VOICE_RESULT = 2;
-    static final int MSG_ABORT_VOICE_RESULT = 3;
-    static final int MSG_COMMAND_RESULT = 4;
-    static final int MSG_CANCEL_RESULT = 5;
+    static final int MSG_PICK_OPTION_RESULT = 2;
+    static final int MSG_COMPLETE_VOICE_RESULT = 3;
+    static final int MSG_ABORT_VOICE_RESULT = 4;
+    static final int MSG_COMMAND_RESULT = 5;
+    static final int MSG_CANCEL_RESULT = 6;
 
+    /**
+     * Base class for voice interaction requests that can be submitted to the interactor.
+     * Do not instantiate this directly -- instead, use the appropriate subclass.
+     */
     public static abstract class Request {
         IVoiceInteractorRequest mRequestInterface;
         Context mContext;
         Activity mActivity;
 
-        public Request() {
+        Request() {
         }
 
         public void cancel() {
@@ -212,22 +243,25 @@
                 String packageName, IVoiceInteractorCallback callback) throws RemoteException;
     }
 
+    /**
+     * Confirms an operation with the user via the trusted system
+     * VoiceInteractionService.  This allows an Activity to complete an unsafe operation that
+     * would require the user to touch the screen when voice interaction mode is not enabled.
+     * The result of the confirmation will be returned through an asynchronous call to
+     * either {@link #onConfirmationResult(boolean, android.os.Bundle)} or
+     * {@link #onCancel()}.
+     *
+     * <p>In some cases this may be a simple yes / no confirmation or the confirmation could
+     * include context information about how the action will be completed
+     * (e.g. booking a cab might include details about how long until the cab arrives)
+     * so the user can give a confirmation.
+     */
     public static class ConfirmationRequest extends Request {
         final CharSequence mPrompt;
         final Bundle mExtras;
 
         /**
-         * Confirms an operation with the user via the trusted system
-         * VoiceInteractionService.  This allows an Activity to complete an unsafe operation that
-         * would require the user to touch the screen when voice interaction mode is not enabled.
-         * The result of the confirmation will be returned through an asynchronous call to
-         * either {@link #onConfirmationResult(boolean, android.os.Bundle)} or
-         * {@link #onCancel()}.
-         *
-         * <p>In some cases this may be a simple yes / no confirmation or the confirmation could
-         * include context information about how the action will be completed
-         * (e.g. booking a cab might include details about how long until the cab arrives)
-         * so the user can give a confirmation.
+         * Create a new confirmation request.
          * @param prompt Optional confirmation text to read to the user as the action being
          * confirmed.
          * @param extras Additional optional information.
@@ -246,19 +280,155 @@
         }
     }
 
+    /**
+     * Select a single option from multiple potential options with the user via the trusted system
+     * VoiceInteractionService. Typically, the application would present this visually as
+     * a list view to allow selecting the option by touch.
+     * The result of the confirmation will be returned through an asynchronous call to
+     * either {@link #onPickOptionResult} or {@link #onCancel()}.
+     */
+    public static class PickOptionRequest extends Request {
+        final CharSequence mPrompt;
+        final Option[] mOptions;
+        final Bundle mExtras;
+
+        /**
+         * Represents a single option that the user may select using their voice.
+         */
+        public static final class Option implements Parcelable {
+            final CharSequence mLabel;
+            ArrayList<CharSequence> mSynonyms;
+            Bundle mExtras;
+
+            /**
+             * Creates an option that a user can select with their voice by matching the label
+             * or one of several synonyms.
+             * @param label The label that will both be matched against what the user speaks
+             * and displayed visually.
+             */
+            public Option(CharSequence label) {
+                mLabel = label;
+            }
+
+            /**
+             * Add a synonym term to the option to indicate an alternative way the content
+             * may be matched.
+             * @param synonym The synonym that will be matched against what the user speaks,
+             * but not displayed.
+             */
+            public Option addSynonym(CharSequence synonym) {
+                if (mSynonyms == null) {
+                    mSynonyms = new ArrayList<>();
+                }
+                mSynonyms.add(synonym);
+                return this;
+            }
+
+            public CharSequence getLabel() {
+                return mLabel;
+            }
+
+            public int countSynonyms() {
+                return mSynonyms != null ? mSynonyms.size() : 0;
+            }
+
+            public CharSequence getSynonymAt(int index) {
+                return mSynonyms != null ? mSynonyms.get(index) : null;
+            }
+
+            /**
+             * Set optional extra information associated with this option.  Note that this
+             * method takes ownership of the supplied extras Bundle.
+             */
+            public void setExtras(Bundle extras) {
+                mExtras = extras;
+            }
+
+            /**
+             * Return any optional extras information associated with this option, or null
+             * if there is none.  Note that this method returns a reference to the actual
+             * extras Bundle in the option, so modifications to it will directly modify the
+             * extras in the option.
+             */
+            public Bundle getExtras() {
+                return mExtras;
+            }
+
+            Option(Parcel in) {
+                mLabel = in.readCharSequence();
+                mSynonyms = in.readCharSequenceList();
+                mExtras = in.readBundle();
+            }
+
+            @Override
+            public int describeContents() {
+                return 0;
+            }
+
+            @Override
+            public void writeToParcel(Parcel dest, int flags) {
+                dest.writeCharSequence(mLabel);
+                dest.writeCharSequenceList(mSynonyms);
+                dest.writeBundle(mExtras);
+            }
+
+            public static final Parcelable.Creator<Option> CREATOR
+                    = new Parcelable.Creator<Option>() {
+                public Option createFromParcel(Parcel in) {
+                    return new Option(in);
+                }
+
+                public Option[] newArray(int size) {
+                    return new Option[size];
+                }
+            };
+        };
+
+        /**
+         * Create a new pick option request.
+         * @param prompt Optional question to be spoken to the user via text to speech.
+         * @param options The set of {@link Option}s the user is selecting from.
+         * @param extras Additional optional information.
+         */
+        public PickOptionRequest(CharSequence prompt, Option[] options, Bundle extras) {
+            mPrompt = prompt;
+            mOptions = options;
+            mExtras = extras;
+        }
+
+        /**
+         * Called when a single option is confirmed or narrowed to one of several options.
+         * @param finished True if the voice interaction has finished making a selection, in
+         * which case {@code selections} contains the final result.  If false, this request is
+         * still active and you will continue to get calls on it.
+         * @param selections Either a single {@link Option} or one of several {@link Option}s the
+         * user has narrowed the choices down to.
+         * @param result Additional optional information.
+         */
+        public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
+        }
+
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startPickOption(packageName, callback, mPrompt, mOptions, mExtras);
+        }
+    }
+
+    /**
+     * Reports that the current interaction was successfully completed with voice, so the
+     * application can report the final status to the user. When the response comes back, the
+     * voice system has handled the request and is ready to switch; at that point the
+     * application can start a new non-voice activity or finish.  Be sure when starting the new
+     * activity to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
+     * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
+     * interaction task.
+     */
     public static class CompleteVoiceRequest extends Request {
         final CharSequence mMessage;
         final Bundle mExtras;
 
         /**
-         * Reports that the current interaction was successfully completed with voice, so the
-         * application can report the final status to the user. When the response comes back, the
-         * voice system has handled the request and is ready to switch; at that point the
-         * application can start a new non-voice activity or finish.  Be sure when starting the new
-         * activity to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
-         * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
-         * interaction task.
-         *
+         * Create a new completed voice interaction request.
          * @param message Optional message to tell user about the completion status of the task.
          * @param extras Additional optional information.
          */
@@ -276,21 +446,23 @@
         }
     }
 
+    /**
+     * Reports that the current interaction can not be complete with voice, so the
+     * application will need to switch to a traditional input UI.  Applications should
+     * only use this when they need to completely bail out of the voice interaction
+     * and switch to a traditional UI.  When the response comes back, the voice
+     * system has handled the request and is ready to switch; at that point the application
+     * can start a new non-voice activity.  Be sure when starting the new activity
+     * to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
+     * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
+     * interaction task.
+     */
     public static class AbortVoiceRequest extends Request {
         final CharSequence mMessage;
         final Bundle mExtras;
 
         /**
-         * Reports that the current interaction can not be complete with voice, so the
-         * application will need to switch to a traditional input UI.  Applications should
-         * only use this when they need to completely bail out of the voice interaction
-         * and switch to a traditional UI.  When the response comes back, the voice
-         * system has handled the request and is ready to switch; at that point the application
-         * can start a new non-voice activity.  Be sure when starting the new activity
-         * to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
-         * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
-         * interaction task.
-         *
+         * Create a new voice abort request.
          * @param message Optional message to tell user about not being able to complete
          * the interaction with voice.
          * @param extras Additional optional information.
@@ -309,25 +481,27 @@
         }
     }
 
+    /**
+     * Execute an extended command using the trusted system VoiceInteractionService.
+     * This allows an Activity to request additional information from the user needed to
+     * complete an action (e.g. booking a table might have several possible times that the
+     * user could select from or an app might need the user to agree to a terms of service).
+     * The result of the confirmation will be returned through an asynchronous call to
+     * either {@link #onCommandResult(boolean, android.os.Bundle)} or
+     * {@link #onCancel()}.
+     *
+     * <p>The command is a string that describes the generic operation to be performed.
+     * The command will determine how the properties in extras are interpreted and the set of
+     * available commands is expected to grow over time.  An example might be
+     * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of
+     * airline check-in.  (This is not an actual working example.)
+     */
     public static class CommandRequest extends Request {
         final String mCommand;
         final Bundle mArgs;
 
         /**
-         * Execute a command using the trusted system VoiceInteractionService.
-         * This allows an Activity to request additional information from the user needed to
-         * complete an action (e.g. booking a table might have several possible times that the
-         * user could select from or an app might need the user to agree to a terms of service).
-         * The result of the confirmation will be returned through an asynchronous call to
-         * either {@link #onCommandResult(boolean, android.os.Bundle)} or
-         * {@link #onCancel()}.
-         *
-         * <p>The command is a string that describes the generic operation to be performed.
-         * The command will determine how the properties in extras are interpreted and the set of
-         * available commands is expected to grow over time.  An example might be
-         * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of
-         * airline check-in.  (This is not an actual working example.)
-         *
+         * Create a new generic command request.
          * @param command The desired command to perform.
          * @param args Additional arguments to control execution of the command.
          */
diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java
index 33d539c2..f16d650 100644
--- a/core/java/android/hardware/camera2/DngCreator.java
+++ b/core/java/android/hardware/camera2/DngCreator.java
@@ -453,7 +453,7 @@
                     height + ") passed to write");
         }
         long capacity = pixels.capacity();
-        long totalSize = rowStride * height + offset;
+        long totalSize = ((long) rowStride) * height + offset;
         if (capacity < totalSize) {
             throw new IllegalArgumentException("Image size " + capacity +
                     " is too small (must be larger than " + totalSize + ")");
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 3d5215b..9d8a1ba 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1059,6 +1059,21 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public final void writeCharSequenceList(ArrayList<CharSequence> val) {
+        if (val != null) {
+            int N = val.size();
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeCharSequence(val.get(i));
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
     public final IBinder[] createBinderArray() {
         int N = readInt();
         if (N >= 0) {
@@ -1828,6 +1843,25 @@
     }
 
     /**
+     * Read and return an ArrayList&lt;CharSequence&gt; object from the parcel.
+     * {@hide}
+     */
+    public final ArrayList<CharSequence> readCharSequenceList() {
+        ArrayList<CharSequence> array = null;
+
+        int length = readInt();
+        if (length >= 0) {
+            array = new ArrayList<CharSequence>(length);
+
+            for (int i = 0 ; i < length ; i++) {
+                array.add(readCharSequence());
+            }
+        }
+
+        return array;
+    }
+
+    /**
      * Read and return a new ArrayList object from the parcel at the current
      * dataPosition().  Returns null if the previously written list object was
      * null.  The given class loader will be used to load any enclosed
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index 29f9ca1..66642de 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -17,6 +17,7 @@
 package android.preference;
 
 import android.annotation.Nullable;
+import android.annotation.XmlRes;
 import android.app.Activity;
 import android.app.Fragment;
 import android.content.Intent;
@@ -294,7 +295,7 @@
      *
      * @param preferencesResId The XML resource ID to inflate.
      */
-    public void addPreferencesFromResource(int preferencesResId) {
+    public void addPreferencesFromResource(@XmlRes int preferencesResId) {
         requirePreferenceManager();
 
         setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(),
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 4cf0e4c..11eaa06 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -18,6 +18,7 @@
 
 import android.app.Dialog;
 import android.app.Instrumentation;
+import android.app.VoiceInteractor;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
@@ -105,6 +106,17 @@
         }
 
         @Override
+        public IVoiceInteractorRequest startPickOption(String callingPackage,
+                IVoiceInteractorCallback callback, CharSequence prompt,
+                VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
+            Request request = newRequest(callback);
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOOO(MSG_START_PICK_OPTION,
+                    new Caller(callingPackage, Binder.getCallingUid()), request,
+                    prompt, options, extras));
+            return request.mInterface;
+        }
+
+        @Override
         public IVoiceInteractorRequest startCompleteVoice(String callingPackage,
                 IVoiceInteractorCallback callback, CharSequence message, Bundle extras) {
             Request request = newRequest(callback);
@@ -232,6 +244,20 @@
             }
         }
 
+        public void sendPickOptionResult(boolean finished,
+                VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
+            try {
+                if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface
+                        + " finished=" + finished + " selections=" + selections
+                        + " result=" + result);
+                if (finished) {
+                    finishRequest();
+                }
+                mCallback.deliverPickOptionResult(mInterface, finished, selections, result);
+            } catch (RemoteException e) {
+            }
+        }
+
         public void sendCompleteVoiceResult(Bundle result) {
             try {
                 if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface
@@ -252,12 +278,14 @@
             }
         }
 
-        public void sendCommandResult(boolean complete, Bundle result) {
+        public void sendCommandResult(boolean finished, Bundle result) {
             try {
                 if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
                         + " result=" + result);
-                finishRequest();
-                mCallback.deliverCommandResult(mInterface, complete, result);
+                if (finished) {
+                    finishRequest();
+                }
+                mCallback.deliverCommandResult(mInterface, finished, result);
             } catch (RemoteException e) {
             }
         }
@@ -283,11 +311,12 @@
     }
 
     static final int MSG_START_CONFIRMATION = 1;
-    static final int MSG_START_COMPLETE_VOICE = 2;
-    static final int MSG_START_ABORT_VOICE = 3;
-    static final int MSG_START_COMMAND = 4;
-    static final int MSG_SUPPORTS_COMMANDS = 5;
-    static final int MSG_CANCEL = 6;
+    static final int MSG_START_PICK_OPTION = 2;
+    static final int MSG_START_COMPLETE_VOICE = 3;
+    static final int MSG_START_ABORT_VOICE = 4;
+    static final int MSG_START_COMMAND = 5;
+    static final int MSG_SUPPORTS_COMMANDS = 6;
+    static final int MSG_CANCEL = 7;
 
     static final int MSG_TASK_STARTED = 100;
     static final int MSG_TASK_FINISHED = 101;
@@ -309,6 +338,15 @@
                     onConfirm((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
                             (Bundle)args.arg4);
                     break;
+                case MSG_START_PICK_OPTION:
+                    args = (SomeArgs)msg.obj;
+                    if (DEBUG) Log.d(TAG, "onPickOption: req=" + ((Request) args.arg2).mInterface
+                            + " prompt=" + args.arg3 + " options=" + args.arg4
+                            + " extras=" + args.arg5);
+                    onPickOption((Caller)args.arg1, (Request)args.arg2, (CharSequence)args.arg3,
+                            (VoiceInteractor.PickOptionRequest.Option[])args.arg4,
+                            (Bundle)args.arg5);
+                    break;
                 case MSG_START_COMPLETE_VOICE:
                     args = (SomeArgs)msg.obj;
                     if (DEBUG) Log.d(TAG, "onCompleteVoice: req=" + ((Request) args.arg2).mInterface
@@ -614,6 +652,26 @@
     }
 
     /**
+     * Set whether this session will keep the device awake while it is running a voice
+     * activity.  By default, the system holds a wake lock for it while in this state,
+     * so that it can work even if the screen is off.  Setting this to false removes that
+     * wake lock, allowing the CPU to go to sleep.  This is typically used if the
+     * session decides it has been waiting too long for a response from the user and
+     * doesn't want to let this continue to drain the battery.
+     *
+     * <p>Passing false here will release the wake lock, and you can call later with
+     * true to re-acquire it.  It will also be automatically re-acquired for you each
+     * time you start a new voice activity task -- that is when you call
+     * {@link #startVoiceActivity}.</p>
+     */
+    public void setKeepAwake(boolean keepAwake) {
+        try {
+            mSystemService.setKeepAwake(mToken, keepAwake);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * Convenience for inflating views.
      */
     public LayoutInflater getLayoutInflater() {
@@ -814,6 +872,22 @@
             Bundle extras);
 
     /**
+     * Request for the user to pick one of N options, corresponding to a
+     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+     *
+     * @param caller Who is making the request.
+     * @param request The active request.
+     * @param prompt The prompt informing the user of what they are picking, as per
+     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+     * @param options The set of options the user is picking from, as per
+     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+     * @param extras Any additional information, as per
+     * {@link android.app.VoiceInteractor.PickOptionRequest VoiceInteractor.PickOptionRequest}.
+     */
+    public abstract void onPickOption(Caller caller, Request request, CharSequence prompt,
+            VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras);
+
+    /**
      * Request to complete the voice interaction session because the voice activity successfully
      * completed its interaction using voice.  Corresponds to
      * {@link android.app.VoiceInteractor.CompleteVoiceRequest
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 668e028..13fb657 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -918,7 +918,7 @@
      *
      * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
-    public int addSpeech(CharSequence text, String packagename, int resourceId) {
+    public int addSpeech(CharSequence text, String packagename, @RawRes int resourceId) {
         synchronized (mStartLock) {
             mUtterances.put(text, makeResourceUri(packagename, resourceId));
             return SUCCESS;
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 9009d6a..a7d9503 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -16,6 +16,7 @@
 
 package android.transition;
 
+import android.annotation.TransitionRes;
 import com.android.internal.R;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -71,7 +72,8 @@
      * @throws android.content.res.Resources.NotFoundException when the
      * transition cannot be loaded
      */
-    public Transition inflateTransition(int resource) {
+    public Transition inflateTransition(@TransitionRes int resource) {
+        //noinspection ResourceType
         XmlResourceParser parser =  mContext.getResources().getXml(resource);
         try {
             return createTransitionFromXml(parser, Xml.asAttributeSet(parser), null);
@@ -98,7 +100,9 @@
      * @throws android.content.res.Resources.NotFoundException when the
      * transition manager cannot be loaded
      */
-    public TransitionManager inflateTransitionManager(int resource, ViewGroup sceneRoot) {
+    public TransitionManager inflateTransitionManager(@TransitionRes int resource,
+            ViewGroup sceneRoot) {
+        //noinspection ResourceType
         XmlResourceParser parser =  mContext.getResources().getXml(resource);
         try {
             return createTransitionManagerFromXml(parser, Xml.asAttributeSet(parser), sceneRoot);
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index d9f6054..9047b1d 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.res.Configuration;
@@ -36,7 +37,7 @@
         super(null);
     }
 
-    public ContextThemeWrapper(Context base, int themeResId) {
+    public ContextThemeWrapper(Context base, @StyleRes int themeResId) {
         super(base);
         mThemeResource = themeResId;
     }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3927096..d345bed 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24,6 +24,7 @@
 import android.annotation.FloatRange;
 import android.annotation.IdRes;
 import android.annotation.IntDef;
+import android.annotation.LayoutRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
@@ -18646,7 +18647,7 @@
      * layout_* parameters.
      * @see LayoutInflater
      */
-    public static View inflate(Context context, int resource, ViewGroup root) {
+    public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
         LayoutInflater factory = LayoutInflater.from(context);
         return factory.inflate(resource, root);
     }
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index f36fd5a..9a92932 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -22,6 +22,7 @@
 import android.annotation.LayoutRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StyleRes;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -753,7 +754,7 @@
      * 0 here will override the animations the window would
      * normally retrieve from its theme.
      */
-    public void setWindowAnimations(int resId) {
+    public void setWindowAnimations(@StyleRes int resId) {
         final WindowManager.LayoutParams attrs = getAttributes();
         attrs.windowAnimations = resId;
         dispatchWindowAttributesChanged(attrs);
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index a5524d8..be43952 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -17,6 +17,7 @@
 package android.view.animation;
 
 import android.annotation.ColorInt;
+import android.annotation.InterpolatorRes;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.RectF;
@@ -388,7 +389,7 @@
      * @param resID The resource identifier of the interpolator to load
      * @attr ref android.R.styleable#Animation_interpolator
      */
-    public void setInterpolator(Context context, int resID) {
+    public void setInterpolator(Context context, @InterpolatorRes int resID) {
         setInterpolator(AnimationUtils.loadInterpolator(context, resID));
     }
 
diff --git a/core/java/android/view/animation/LayoutAnimationController.java b/core/java/android/view/animation/LayoutAnimationController.java
index 882e738..df2f18c 100644
--- a/core/java/android/view/animation/LayoutAnimationController.java
+++ b/core/java/android/view/animation/LayoutAnimationController.java
@@ -16,6 +16,8 @@
 
 package android.view.animation;
 
+import android.annotation.AnimRes;
+import android.annotation.InterpolatorRes;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -180,7 +182,7 @@
      *
      * @attr ref android.R.styleable#LayoutAnimation_animation
      */
-    public void setAnimation(Context context, int resourceID) {
+    public void setAnimation(Context context, @AnimRes int resourceID) {
         setAnimation(AnimationUtils.loadAnimation(context, resourceID));
     }
 
@@ -225,7 +227,7 @@
      *
      * @attr ref android.R.styleable#LayoutAnimation_interpolator
      */
-    public void setInterpolator(Context context, int resourceID) {
+    public void setInterpolator(Context context, @InterpolatorRes int resourceID) {
         setInterpolator(AnimationUtils.loadInterpolator(context, resourceID));
     }
 
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 9d3a5dc..d6f2276 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -15,6 +15,7 @@
  */
 package android.widget;
 
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -86,7 +87,7 @@
      * @param resId theme used to inflate popup menus
      * @see #getPopupTheme()
      */
-    public void setPopupTheme(int resId) {
+    public void setPopupTheme(@StyleRes int resId) {
         if (mPopupTheme != resId) {
             mPopupTheme = resId;
             if (resId == 0) {
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 89e508f..ae94a10 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -19,6 +19,7 @@
 import android.annotation.ArrayRes;
 import android.annotation.IdRes;
 import android.annotation.LayoutRes;
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Resources;
 import android.util.Log;
@@ -133,7 +134,7 @@
      *                 instantiating views.
      * @param objects The objects to represent in the ListView.
      */
-    public ArrayAdapter(Context context, @LayoutRes int resource, T[] objects) {
+    public ArrayAdapter(Context context, @LayoutRes int resource, @NonNull T[] objects) {
         this(context, resource, 0, Arrays.asList(objects));
     }
 
@@ -146,7 +147,8 @@
      * @param textViewResourceId The id of the TextView within the layout resource to be populated
      * @param objects The objects to represent in the ListView.
      */
-    public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId, T[] objects) {
+    public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId,
+            @NonNull T[] objects) {
         this(context, resource, textViewResourceId, Arrays.asList(objects));
     }
 
@@ -158,7 +160,7 @@
      *                 instantiating views.
      * @param objects The objects to represent in the ListView.
      */
-    public ArrayAdapter(Context context, @LayoutRes int resource, List<T> objects) {
+    public ArrayAdapter(Context context, @LayoutRes int resource, @NonNull List<T> objects) {
         this(context, resource, 0, objects);
     }
 
@@ -171,7 +173,8 @@
      * @param textViewResourceId The id of the TextView within the layout resource to be populated
      * @param objects The objects to represent in the ListView.
      */
-    public ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects) {
+    public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId,
+            @NonNull List<T> objects) {
         mContext = context;
         mInflater = LayoutInflater.from(context);
         mResource = mDropDownResource = resource;
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index fe143dec..133e102 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -22,6 +22,7 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
@@ -326,7 +327,7 @@
         refreshDrawablePressedState();
     }
 
-    public void setStyle(int resId) {
+    public void setStyle(@StyleRes int resId) {
         final Context context = mList.getContext();
         final TypedArray ta = context.obtainStyledAttributes(null,
                 com.android.internal.R.styleable.FastScroll, android.R.attr.fastScrollStyle, resId);
diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java
index a656712..2008ba8f 100644
--- a/core/java/android/widget/SimpleAdapter.java
+++ b/core/java/android/widget/SimpleAdapter.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import android.annotation.IdRes;
+import android.annotation.LayoutRes;
 import android.content.Context;
 import android.content.res.Resources;
 import android.view.ContextThemeWrapper;
@@ -82,7 +84,7 @@
      *        in the from parameter.
      */
     public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,
-            int resource, String[] from, int[] to) {
+            @LayoutRes int resource, String[] from, @IdRes int[] to) {
         mData = data;
         mResource = mDropDownResource = resource;
         mFrom = from;
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index d2430bc..087406a 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -17,8 +17,12 @@
 package android.widget;
 
 import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.MenuRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
+import android.annotation.StyleRes;
 import android.app.ActionBar;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -296,7 +300,7 @@
      * @param resId theme used to inflate popup menus
      * @see #getPopupTheme()
      */
-    public void setPopupTheme(int resId) {
+    public void setPopupTheme(@StyleRes int resId) {
         if (mPopupTheme != resId) {
             mPopupTheme = resId;
             if (resId == 0) {
@@ -331,7 +335,7 @@
      *
      * @param resId ID of a drawable resource
      */
-    public void setLogo(int resId) {
+    public void setLogo(@DrawableRes int resId) {
         setLogo(getContext().getDrawable(resId));
     }
 
@@ -481,7 +485,7 @@
      *
      * @param resId String resource id
      */
-    public void setLogoDescription(int resId) {
+    public void setLogoDescription(@StringRes int resId) {
         setLogoDescription(getContext().getText(resId));
     }
 
@@ -566,7 +570,7 @@
      *
      * @param resId Resource ID of a string to set as the title
      */
-    public void setTitle(int resId) {
+    public void setTitle(@StringRes int resId) {
         setTitle(getContext().getText(resId));
     }
 
@@ -621,7 +625,7 @@
      *
      * @param resId String resource ID
      */
-    public void setSubtitle(int resId) {
+    public void setSubtitle(@StringRes int resId) {
         setSubtitle(getContext().getText(resId));
     }
 
@@ -663,7 +667,7 @@
      * Sets the text color, size, style, hint color, and highlight color
      * from the specified TextAppearance resource.
      */
-    public void setTitleTextAppearance(Context context, int resId) {
+    public void setTitleTextAppearance(Context context, @StyleRes int resId) {
         mTitleTextAppearance = resId;
         if (mTitleTextView != null) {
             mTitleTextView.setTextAppearance(context, resId);
@@ -674,7 +678,7 @@
      * Sets the text color, size, style, hint color, and highlight color
      * from the specified TextAppearance resource.
      */
-    public void setSubtitleTextAppearance(Context context, int resId) {
+    public void setSubtitleTextAppearance(Context context, @StyleRes int resId) {
         mSubtitleTextAppearance = resId;
         if (mSubtitleTextView != null) {
             mSubtitleTextView.setTextAppearance(context, resId);
@@ -729,7 +733,7 @@
      *
      * @attr ref android.R.styleable#Toolbar_navigationContentDescription
      */
-    public void setNavigationContentDescription(int resId) {
+    public void setNavigationContentDescription(@StringRes int resId) {
         setNavigationContentDescription(resId != 0 ? getContext().getText(resId) : null);
     }
 
@@ -766,7 +770,7 @@
      *
      * @attr ref android.R.styleable#Toolbar_navigationIcon
      */
-    public void setNavigationIcon(int resId) {
+    public void setNavigationIcon(@DrawableRes int resId) {
         setNavigationIcon(getContext().getDrawable(resId));
     }
 
@@ -972,7 +976,7 @@
      *
      * @param resId ID of a menu resource to inflate
      */
-    public void inflateMenu(int resId) {
+    public void inflateMenu(@MenuRes int resId) {
         getMenuInflater().inflate(resId, getMenu());
     }
 
diff --git a/core/java/android/widget/ViewAnimator.java b/core/java/android/widget/ViewAnimator.java
index f30fdd8..1580f51 100644
--- a/core/java/android/widget/ViewAnimator.java
+++ b/core/java/android/widget/ViewAnimator.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 
+import android.annotation.AnimRes;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -309,7 +310,7 @@
      * @see #getInAnimation()
      * @see #setInAnimation(android.view.animation.Animation)
      */
-    public void setInAnimation(Context context, int resourceID) {
+    public void setInAnimation(Context context, @AnimRes int resourceID) {
         setInAnimation(AnimationUtils.loadAnimation(context, resourceID));
     }
 
@@ -322,7 +323,7 @@
      * @see #getOutAnimation()
      * @see #setOutAnimation(android.view.animation.Animation)
      */
-    public void setOutAnimation(Context context, int resourceID) {
+    public void setOutAnimation(Context context, @AnimRes int resourceID) {
         setOutAnimation(AnimationUtils.loadAnimation(context, resourceID));
     }
 
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 8f549a6..6450d52 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -32,6 +32,7 @@
     boolean showSessionFromSession(IBinder token, in Bundle sessionArgs, int flags);
     boolean hideSessionFromSession(IBinder token);
     int startVoiceActivity(IBinder token, in Intent intent, String resolvedType);
+    void setKeepAwake(IBinder token, boolean keepAwake);
     void finish(IBinder token);
 
     /**
diff --git a/core/java/com/android/internal/app/IVoiceInteractor.aidl b/core/java/com/android/internal/app/IVoiceInteractor.aidl
index 3e0b021..84e9cf0 100644
--- a/core/java/com/android/internal/app/IVoiceInteractor.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractor.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.app.VoiceInteractor;
 import android.os.Bundle;
 
 import com.android.internal.app.IVoiceInteractorCallback;
@@ -27,6 +28,9 @@
 interface IVoiceInteractor {
     IVoiceInteractorRequest startConfirmation(String callingPackage,
             IVoiceInteractorCallback callback, CharSequence prompt, in Bundle extras);
+    IVoiceInteractorRequest startPickOption(String callingPackage,
+            IVoiceInteractorCallback callback, CharSequence prompt,
+            in VoiceInteractor.PickOptionRequest.Option[] options, in Bundle extras);
     IVoiceInteractorRequest startCompleteVoice(String callingPackage,
             IVoiceInteractorCallback callback, CharSequence message, in Bundle extras);
     IVoiceInteractorRequest startAbortVoice(String callingPackage,
diff --git a/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl b/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
index dcd5759..1331e74 100644
--- a/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.app.VoiceInteractor;
 import android.os.Bundle;
 
 import com.android.internal.app.IVoiceInteractorRequest;
@@ -26,8 +27,10 @@
 oneway interface IVoiceInteractorCallback {
     void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
             in Bundle result);
+    void deliverPickOptionResult(IVoiceInteractorRequest request, boolean finished,
+            in VoiceInteractor.PickOptionRequest.Option[] selections, in Bundle result);
     void deliverCompleteVoiceResult(IVoiceInteractorRequest request, in Bundle result);
     void deliverAbortVoiceResult(IVoiceInteractorRequest request, in Bundle result);
-    void deliverCommandResult(IVoiceInteractorRequest request, boolean complete, in Bundle result);
+    void deliverCommandResult(IVoiceInteractorRequest request, boolean finished, in Bundle result);
     void deliverCancel(IVoiceInteractorRequest request);
 }
diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java
index 99286cb..113768e 100644
--- a/core/java/com/android/internal/os/HandlerCaller.java
+++ b/core/java/com/android/internal/os/HandlerCaller.java
@@ -164,6 +164,15 @@
         return mH.obtainMessage(what, arg1, 0, args);
     }
 
+    public Message obtainMessageIIOOO(int what, int arg1, int arg2, Object arg3, Object arg4,
+            Object arg5) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = arg3;
+        args.arg2 = arg4;
+        args.arg3 = arg5;
+        return mH.obtainMessage(what, arg1, arg2, args);
+    }
+
     public Message obtainMessageOO(int what, Object arg1, Object arg2) {
         SomeArgs args = SomeArgs.obtain();
         args.arg1 = arg1;
diff --git a/core/jni/android_database_SQLiteGlobal.cpp b/core/jni/android_database_SQLiteGlobal.cpp
index d0c592e..0a1c9f7 100644
--- a/core/jni/android_database_SQLiteGlobal.cpp
+++ b/core/jni/android_database_SQLiteGlobal.cpp
@@ -35,14 +35,18 @@
 
 
 // Called each time a message is logged.
-static void sqliteLogCallback(void* data, int iErrCode, const char* zMsg) {
+static void sqliteLogCallback(void* data, int err, const char* msg) {
     bool verboseLog = !!data;
-    if (iErrCode == 0 || iErrCode == SQLITE_CONSTRAINT || iErrCode == SQLITE_SCHEMA) {
+    int errType = err & 255;
+    if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA
+            || errType == SQLITE_NOTICE || err == SQLITE_WARNING_AUTOINDEX) {
         if (verboseLog) {
-            ALOG(LOG_VERBOSE, SQLITE_LOG_TAG, "(%d) %s\n", iErrCode, zMsg);
+            ALOG(LOG_VERBOSE, SQLITE_LOG_TAG, "(%d) %s\n", err, msg);
         }
+    } else if (errType == SQLITE_WARNING) {
+        ALOG(LOG_WARN, SQLITE_LOG_TAG, "(%d) %s\n", err, msg);
     } else {
-        ALOG(LOG_ERROR, SQLITE_LOG_TAG, "(%d) %s\n", iErrCode, zMsg);
+        ALOG(LOG_ERROR, SQLITE_LOG_TAG, "(%d) %s\n", err, msg);
     }
 }
 
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index bddd224..69d6891 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import android.annotation.ColorInt;
 import android.annotation.NonNull;
 
 /**
@@ -36,7 +37,7 @@
      * @see #setColor(int)
      * @see #setMode(android.graphics.PorterDuff.Mode)
      */
-    public PorterDuffColorFilter(int color, @NonNull PorterDuff.Mode mode) {
+    public PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
         mColor = color;
         mMode = mode;
         update();
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 16760c7..56876e94 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -521,7 +521,7 @@
      * {@link #setTintList(ColorStateList) tint}.
      * </p>
      */
-    public void setColorFilter(int color, @NonNull PorterDuff.Mode mode) {
+    public void setColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
         setColorFilter(new PorterDuffColorFilter(color, mode));
     }
 
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 3c9ca4e..ebf73da 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -1972,7 +1972,7 @@
                     (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL);
                 if (complexity == null) {
                     complexity = flacComplexity;
-                } else if (flacComplexity != null && complexity != flacComplexity) {
+                } else if (flacComplexity != null && !complexity.equals(flacComplexity)) {
                     throw new IllegalArgumentException(
                             "conflicting values for complexity and " +
                             "flac-compression-level");
@@ -1985,7 +1985,7 @@
                 Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE);
                 if (profile == null) {
                     profile = aacProfile;
-                } else if (aacProfile != null && aacProfile != profile) {
+                } else if (aacProfile != null && !aacProfile.equals(profile)) {
                     throw new IllegalArgumentException(
                             "conflicting values for profile and aac-profile");
                 }
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index c44fbe6..0c1c7e9 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -606,14 +606,14 @@
      * Sets the value of an integer key.
      */
     public final void setInteger(String name, int value) {
-        mMap.put(name, new Integer(value));
+        mMap.put(name, Integer.valueOf(value));
     }
 
     /**
      * Sets the value of a long key.
      */
     public final void setLong(String name, long value) {
-        mMap.put(name, new Long(value));
+        mMap.put(name, Long.valueOf(value));
     }
 
     /**
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
index 69e0ea6..91c53fa 100644
--- a/media/java/android/media/WebVttRenderer.java
+++ b/media/java/android/media/WebVttRenderer.java
@@ -433,7 +433,9 @@
                     mRegionId.equals(cue.mRegionId) &&
                     mSnapToLines == cue.mSnapToLines &&
                     mAutoLinePosition == cue.mAutoLinePosition &&
-                    (mAutoLinePosition || mLinePosition == cue.mLinePosition) &&
+                    (mAutoLinePosition ||
+                            ((mLinePosition != null && mLinePosition.equals(cue.mLinePosition)) ||
+                             (mLinePosition == null && cue.mLinePosition == null))) &&
                     mTextPosition == cue.mTextPosition &&
                     mSize == cue.mSize &&
                     mAlignment == cue.mAlignment &&
diff --git a/media/java/android/media/midi/MidiDeviceInfo.java b/media/java/android/media/midi/MidiDeviceInfo.java
index f7fad3d..93e0939 100644
--- a/media/java/android/media/midi/MidiDeviceInfo.java
+++ b/media/java/android/media/midi/MidiDeviceInfo.java
@@ -173,8 +173,16 @@
         mId = id;
         mInputPortCount = numInputPorts;
         mOutputPortCount = numOutputPorts;
-        mInputPortNames = inputPortNames;
-        mOutputPortNames = outputPortNames;
+        if (inputPortNames == null) {
+            mInputPortNames = new String[numInputPorts];
+        } else {
+            mInputPortNames = inputPortNames;
+        }
+        if (outputPortNames == null) {
+            mOutputPortNames = new String[numOutputPorts];
+        } else {
+            mOutputPortNames = outputPortNames;
+        }
         mProperties = properties;
         mIsPrivate = isPrivate;
     }
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index e0aacd6..0284171 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -42,6 +42,7 @@
     private final int mType;
     private final String mId;
     private final String mLanguage;
+    private final String mDescription;
     private final int mAudioChannelCount;
     private final int mAudioSampleRate;
     private final int mVideoWidth;
@@ -49,12 +50,13 @@
     private final float mVideoFrameRate;
     private final Bundle mExtra;
 
-    private TvTrackInfo(int type, String id, String language, int audioChannelCount,
-            int audioSampleRate, int videoWidth, int videoHeight, float videoFrameRate,
-            Bundle extra) {
+    private TvTrackInfo(int type, String id, String language, String description,
+            int audioChannelCount, int audioSampleRate, int videoWidth, int videoHeight,
+            float videoFrameRate, Bundle extra) {
         mType = type;
         mId = id;
         mLanguage = language;
+        mDescription = description;
         mAudioChannelCount = audioChannelCount;
         mAudioSampleRate = audioSampleRate;
         mVideoWidth = videoWidth;
@@ -67,6 +69,7 @@
         mType = in.readInt();
         mId = in.readString();
         mLanguage = in.readString();
+        mDescription = in.readString();
         mAudioChannelCount = in.readInt();
         mAudioSampleRate = in.readInt();
         mVideoWidth = in.readInt();
@@ -99,6 +102,13 @@
     }
 
     /**
+     * Returns a user readable description for the current track.
+     */
+    public final String getDescription() {
+        return mDescription;
+    }
+
+    /**
      * Returns the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
      */
     public final int getAudioChannelCount() {
@@ -174,6 +184,7 @@
         dest.writeInt(mType);
         dest.writeString(mId);
         dest.writeString(mLanguage);
+        dest.writeString(mDescription);
         dest.writeInt(mAudioChannelCount);
         dest.writeInt(mAudioSampleRate);
         dest.writeInt(mVideoWidth);
@@ -202,6 +213,7 @@
         private final String mId;
         private final int mType;
         private String mLanguage;
+        private String mDescription;
         private int mAudioChannelCount;
         private int mAudioSampleRate;
         private int mVideoWidth;
@@ -241,6 +253,16 @@
         }
 
         /**
+         * Sets a user readable description for the current track.
+         *
+         * @param description The user readable description.
+         */
+        public final Builder setDescription(String description) {
+            mDescription = description;
+            return this;
+        }
+
+        /**
          * Sets the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
          *
          * @param audioChannelCount The audio channel count.
@@ -325,8 +347,8 @@
          * @return The new {@link TvTrackInfo} instance
          */
         public TvTrackInfo build() {
-            return new TvTrackInfo(mType, mId, mLanguage, mAudioChannelCount, mAudioSampleRate,
-                    mVideoWidth, mVideoHeight, mVideoFrameRate, mExtra);
+            return new TvTrackInfo(mType, mId, mLanguage, mDescription, mAudioChannelCount,
+                    mAudioSampleRate, mVideoWidth, mVideoHeight, mVideoFrameRate, mExtra);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 6c1cdcd..1e40bab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -162,11 +162,6 @@
     public void updateNotification(NotificationData.Entry headsUp, boolean alert) {
         if (DEBUG) Log.v(TAG, "updateNotification");
 
-        if (alert) {
-            mBar.scheduleHeadsUpDecay(mHeadsUpNotificationDecay);
-        }
-        invalidate();
-
         if (mHeadsUp == headsUp) {
             resetViewForHeadsup();
             // This is an in-place update.  Noting more to do.
@@ -197,9 +192,11 @@
             }
 
             mHeadsUp.setInterruption();
-
+        }
+        if (alert) {
             // Make sure the heads up window is open.
             mBar.scheduleHeadsUpOpen();
+            mBar.scheduleHeadsUpDecay(mHeadsUpNotificationDecay);
         }
     }
 
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index d352130..83aeedd 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -239,8 +239,10 @@
                            FieldPacker v, LaunchOptions sc) {
         // TODO: Is this necessary if nScriptForEach calls validate as well?
         mRS.validate();
-        for (Allocation ain : ains) {
-          mRS.validateObject(ain);
+        if (ains != null) {
+            for (Allocation ain : ains) {
+                mRS.validateObject(ain);
+            }
         }
         mRS.validateObject(aout);
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e7952c1..a366c7b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -51,6 +51,8 @@
 import android.graphics.Rect;
 import android.os.BatteryStats;
 import android.os.PersistableBundle;
+import android.os.PowerManager;
+import android.os.WorkSource;
 import android.os.storage.IMountService;
 import android.os.storage.StorageManager;
 import android.service.voice.IVoiceInteractionSession;
@@ -991,7 +993,14 @@
      * Set while we are running a voice interaction.  This overrides
      * sleeping while it is active.
      */
-    private boolean mRunningVoice = false;
+    private IVoiceInteractionSession mRunningVoice;
+
+    /**
+     * We want to hold a wake lock while running a voice interaction session, since
+     * this may happen with the screen off and we need to keep the CPU running to
+     * be able to continue to interact with the user.
+     */
+    PowerManager.WakeLock mVoiceWakeLock;
 
     /**
      * State of external calls telling us if the device is awake or asleep.
@@ -2269,6 +2278,9 @@
     public void initPowerManagement() {
         mStackSupervisor.initPowerManagement();
         mBatteryStatsService.initPowerManagement();
+        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
+        mVoiceWakeLock.setReferenceCounted(false);
     }
 
     @Override
@@ -2472,7 +2484,7 @@
             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
             mFocusedActivity = r;
             if (r.task != null && r.task.voiceInteractor != null) {
-                startRunningVoiceLocked();
+                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
             } else {
                 finishRunningVoiceLocked();
             }
@@ -3628,6 +3640,19 @@
     }
 
     @Override
+    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
+        synchronized (this) {
+            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
+                if (keepAwake) {
+                    mVoiceWakeLock.acquire();
+                } else {
+                    mVoiceWakeLock.release();
+                }
+            }
+        }
+    }
+
+    @Override
     public boolean startNextMatchingActivity(IBinder callingActivity,
             Intent intent, Bundle options) {
         // Refuse possible leaked file descriptors
@@ -9685,8 +9710,8 @@
     }
 
     void finishRunningVoiceLocked() {
-        if (mRunningVoice) {
-            mRunningVoice = false;
+        if (mRunningVoice != null) {
+            mRunningVoice = null;
             updateSleepIfNeededLocked();
         }
     }
@@ -9709,7 +9734,7 @@
 
     private boolean shouldSleepLocked() {
         // Resume applications while running a voice interactor.
-        if (mRunningVoice) {
+        if (mRunningVoice != null) {
             return false;
         }
 
@@ -9810,10 +9835,14 @@
                 + " mSleeping=" + mSleeping);
     }
 
-    void startRunningVoiceLocked() {
-        if (!mRunningVoice) {
-            mRunningVoice = true;
-            updateSleepIfNeededLocked();
+    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
+        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
+        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
+            if (mRunningVoice == null) {
+                mVoiceWakeLock.acquire();
+                updateSleepIfNeededLocked();
+            }
+            mRunningVoice = session;
         }
     }
 
@@ -12813,8 +12842,11 @@
                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
                     + lockScreenShownToString());
-            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
-                    + " mTestPssMode=" + mTestPssMode);
+            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
+            if (mRunningVoice != null) {
+                pw.println("  mRunningVoice=" + mRunningVoice);
+                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
+            }
         }
         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
                 || mOrigWaitForDebugger) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index be95268..456ed33 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -869,7 +869,7 @@
 
         // If we are not going to sleep, we want to ensure the device is
         // awake until the next activity is started.
-        if (!mService.isSleepingOrShuttingDown()) {
+        if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
             mStackSupervisor.acquireLaunchWakelock();
         }
 
@@ -1671,6 +1671,8 @@
             }
         }
 
+        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
+
         // We need to start pausing the current activity so the top one
         // can be resumed...
         boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index cbbb11a8..f56f65f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -84,6 +84,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.WorkSource;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.service.voice.IVoiceInteractionSession;
@@ -316,8 +317,7 @@
     void initPowerManagement() {
         PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
         mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
-        mLaunchingActivity =
-                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
+        mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*launch*");
         mLaunchingActivity.setReferenceCounted(false);
     }
 
@@ -2273,6 +2273,10 @@
         }
     }
 
+    void setLaunchSource(int uid) {
+        mLaunchingActivity.setWorkSource(new WorkSource(uid));
+    }
+
     void acquireLaunchWakelock() {
         if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
             throw new IllegalStateException("Calling must be system uid");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 6b8c49c..f032ccf 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -479,6 +479,24 @@
         }
 
         @Override
+        public void setKeepAwake(IBinder token, boolean keepAwake) {
+            synchronized (this) {
+                if (mImpl == null) {
+                    Slog.w(TAG, "setKeepAwake without running voice interaction service");
+                    return;
+                }
+                final int callingPid = Binder.getCallingPid();
+                final int callingUid = Binder.getCallingUid();
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mImpl.setKeepAwakeLocked(callingPid, callingUid, token, keepAwake);
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
+        @Override
         public void finish(IBinder token) {
             synchronized (this) {
                 if (mImpl == null) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 9e92867..5a91b88 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -174,6 +174,18 @@
         }
     }
 
+    public void setKeepAwakeLocked(int callingPid, int callingUid, IBinder token,
+            boolean keepAwake) {
+        try {
+            if (mActiveSession == null || token != mActiveSession.mToken) {
+                Slog.w(TAG, "setKeepAwake does not match active session");
+                return;
+            }
+            mAm.setVoiceKeepAwake(mActiveSession.mSession, keepAwake);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Unexpected remote error", e);
+        }
+    }
 
     public void finishLocked(int callingPid, int callingUid, IBinder token) {
         if (mActiveSession == null || token != mActiveSession.mToken) {
diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml
index f4648b57..8c8151d 100644
--- a/tests/VoiceInteraction/res/layout/test_interaction.xml
+++ b/tests/VoiceInteraction/res/layout/test_interaction.xml
@@ -41,6 +41,13 @@
         android:text="@string/completeVoice"
         />
 
+    <Button android:id="@+id/pick"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:text="@string/pickVoice"
+        />
+
     <Button android:id="@+id/abort"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index 9f99c97..5331457 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -22,7 +22,7 @@
     <string name="complete">Complete</string>
     <string name="abortVoice">Abort Voice</string>
     <string name="completeVoice">Complete Voice</string>
+    <string name="pickVoice">Pick Voice</string>
     <string name="cancelVoice">Cancel</string>
 
 </resources>
-
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index bcfc6f4..ad339be 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -18,6 +18,7 @@
 
 import android.app.AssistContent;
 import android.app.AssistStructure;
+import android.app.VoiceInteractor;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
@@ -47,12 +48,15 @@
     static final int STATE_IDLE = 0;
     static final int STATE_LAUNCHING = 1;
     static final int STATE_CONFIRM = 2;
-    static final int STATE_COMMAND = 3;
-    static final int STATE_ABORT_VOICE = 4;
-    static final int STATE_COMPLETE_VOICE = 5;
-    static final int STATE_DONE=6;
+    static final int STATE_PICK_OPTION = 3;
+    static final int STATE_COMMAND = 4;
+    static final int STATE_ABORT_VOICE = 5;
+    static final int STATE_COMPLETE_VOICE = 6;
+    static final int STATE_DONE=7;
 
     int mState = STATE_IDLE;
+    VoiceInteractor.PickOptionRequest.Option[] mPendingOptions;
+    CharSequence mPendingPrompt;
     Request mPendingRequest;
 
     MainInteractionSession(Context context) {
@@ -154,7 +158,8 @@
             mAssistVisualizer.setVisibility(View.GONE);
         }
         mStartButton.setEnabled(mState == STATE_IDLE);
-        mConfirmButton.setEnabled(mState == STATE_CONFIRM || mState == STATE_COMMAND);
+        mConfirmButton.setEnabled(mState == STATE_CONFIRM || mState == STATE_PICK_OPTION
+                || mState == STATE_COMMAND);
         mAbortButton.setEnabled(mState == STATE_ABORT_VOICE);
         mCompleteButton.setEnabled(mState == STATE_COMPLETE_VOICE);
     }
@@ -167,10 +172,32 @@
         } else if (v == mConfirmButton) {
             if (mState == STATE_CONFIRM) {
                 mPendingRequest.sendConfirmResult(true, null);
-            } else {
+                mPendingRequest = null;
+                mState = STATE_LAUNCHING;
+            } else if (mState == STATE_PICK_OPTION) {
+                int numReturn = mPendingOptions.length/2;
+                if (numReturn <= 0) {
+                    numReturn = 1;
+                }
+                VoiceInteractor.PickOptionRequest.Option[] picked
+                        = new VoiceInteractor.PickOptionRequest.Option[numReturn];
+                for (int i=0; i<picked.length; i++) {
+                    picked[i] = mPendingOptions[i*2];
+                }
+                mPendingOptions = picked;
+                if (picked.length <= 1) {
+                    mPendingRequest.sendPickOptionResult(true, picked, null);
+                    mPendingRequest = null;
+                    mState = STATE_LAUNCHING;
+                } else {
+                    mPendingRequest.sendPickOptionResult(false, picked, null);
+                    updatePickText();
+                }
+            } else if (mPendingRequest != null) {
                 mPendingRequest.sendCommandResult(true, null);
+                mPendingRequest = null;
+                mState = STATE_LAUNCHING;
             }
-            mPendingRequest = null;
         } else if (v == mAbortButton) {
             mPendingRequest.sendAbortVoiceResult(null);
             mPendingRequest = null;
@@ -178,6 +205,7 @@
             mPendingRequest.sendCompleteVoiceResult(null);
             mPendingRequest = null;
         }
+        updateState();
     }
 
     @Override
@@ -198,13 +226,40 @@
     public void onConfirm(Caller caller, Request request, CharSequence prompt, Bundle extras) {
         Log.i(TAG, "onConfirm: prompt=" + prompt + " extras=" + extras);
         mText.setText(prompt);
-        mStartButton.setText("Confirm");
+        mConfirmButton.setText("Confirm");
         mPendingRequest = request;
+        mPendingPrompt = prompt;
         mState = STATE_CONFIRM;
         updateState();
     }
 
     @Override
+    public void onPickOption(Caller caller, Request request, CharSequence prompt,
+            VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) {
+        Log.i(TAG, "onPickOption: prompt=" + prompt + " options=" + options + " extras=" + extras);
+        mConfirmButton.setText("Pick Option");
+        mPendingRequest = request;
+        mPendingPrompt = prompt;
+        mPendingOptions = options;
+        mState = STATE_PICK_OPTION;
+        updatePickText();
+        updateState();
+    }
+
+    void updatePickText() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(mPendingPrompt);
+        sb.append(": ");
+        for (int i=0; i<mPendingOptions.length; i++) {
+            if (i > 0) {
+                sb.append(", ");
+            }
+            sb.append(mPendingOptions[i].getLabel());
+        }
+        mText.setText(sb.toString());
+    }
+
+    @Override
     public void onCompleteVoice(Caller caller, Request request, CharSequence message, Bundle extras) {
         Log.i(TAG, "onCompleteVoice: message=" + message + " extras=" + extras);
         mText.setText(message);
@@ -226,7 +281,7 @@
     public void onCommand(Caller caller, Request request, String command, Bundle extras) {
         Log.i(TAG, "onCommand: command=" + command + " extras=" + extras);
         mText.setText("Command: " + command);
-        mStartButton.setText("Finish Command");
+        mConfirmButton.setText("Finish Command");
         mPendingRequest = request;
         mState = STATE_COMMAND;
         updateState();
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index 023e0ec..e195c30 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -26,14 +26,17 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.TextView;
 
 public class TestInteractionActivity extends Activity implements View.OnClickListener {
     static final String TAG = "TestInteractionActivity";
 
     VoiceInteractor mInteractor;
     VoiceInteractor.Request mCurrentRequest = null;
+    TextView mLog;
     Button mAbortButton;
     Button mCompleteButton;
+    Button mPickButton;
     Button mCancelButton;
 
     @Override
@@ -54,10 +57,13 @@
         }
 
         setContentView(R.layout.test_interaction);
+        mLog = (TextView)findViewById(R.id.log);
         mAbortButton = (Button)findViewById(R.id.abort);
         mAbortButton.setOnClickListener(this);
         mCompleteButton = (Button)findViewById(R.id.complete);
         mCompleteButton.setOnClickListener(this);
+        mPickButton = (Button)findViewById(R.id.pick);
+        mPickButton.setOnClickListener(this);
         mCancelButton = (Button)findViewById(R.id.cancel);
         mCancelButton.setOnClickListener(this);
 
@@ -92,11 +98,13 @@
                 @Override
                 public void onCancel() {
                     Log.i(TAG, "Canceled!");
+                    mLog.append("Canceled abort\n");
                 }
 
                 @Override
                 public void onAbortResult(Bundle result) {
                     Log.i(TAG, "Abort result: result=" + result);
+                    mLog.append("Abort: result=" + result + "\n");
                     getActivity().finish();
                 }
             };
@@ -107,15 +115,56 @@
                 @Override
                 public void onCancel() {
                     Log.i(TAG, "Canceled!");
+                    mLog.append("Canceled complete\n");
                 }
 
                 @Override
                 public void onCompleteResult(Bundle result) {
                     Log.i(TAG, "Complete result: result=" + result);
+                    mLog.append("Complete: result=" + result + "\n");
                     getActivity().finish();
                 }
             };
             mInteractor.submitRequest(req);
+        } else if (v == mPickButton) {
+            VoiceInteractor.PickOptionRequest.Option[] options =
+                    new VoiceInteractor.PickOptionRequest.Option[5];
+            options[0] = new VoiceInteractor.PickOptionRequest.Option("One");
+            options[1] = new VoiceInteractor.PickOptionRequest.Option("Two");
+            options[2] = new VoiceInteractor.PickOptionRequest.Option("Three");
+            options[3] = new VoiceInteractor.PickOptionRequest.Option("Four");
+            options[4] = new VoiceInteractor.PickOptionRequest.Option("Five");
+            VoiceInteractor.PickOptionRequest req = new VoiceInteractor.PickOptionRequest(
+                    "Need to pick something", options, null) {
+                @Override
+                public void onCancel() {
+                    Log.i(TAG, "Canceled!");
+                    mLog.append("Canceled pick\n");
+                }
+
+                @Override
+                public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
+                    Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections
+                            + " result=" + result);
+                    StringBuilder sb = new StringBuilder();
+                    if (finished) {
+                        sb.append("Pick final result: ");
+                    } else {
+                        sb.append("Pick intermediate result: ");
+                    }
+                    for (int i=0; i<selections.length; i++) {
+                        if (i >= 1) {
+                            sb.append(", ");
+                        }
+                        sb.append(selections[i].getLabel());
+                    }
+                    mLog.append(sb.toString());
+                    if (finished) {
+                        getActivity().finish();
+                    }
+                }
+            };
+            mInteractor.submitRequest(req);
         } else if (v == mCancelButton && mCurrentRequest != null) {
             Log.i(TAG, "Cancel request");
             mCurrentRequest.cancel();
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index b38b2ed..d2cd2d6 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -466,7 +466,7 @@
     block->restart();
 
     Vector<namespace_entry> namespaces;
-    
+
     ResXMLTree::event_code_t code;
     int depth = 0;
     while ((code=block->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
@@ -520,7 +520,12 @@
                 printf("\n");
             }
         } else if (code == ResXMLTree::END_TAG) {
-            depth--;
+            // Invalid tag nesting can be misused to break the parsing
+            // code below. Break if detected.
+            if (--depth < 0) {
+                printf("***BAD DEPTH in XMLBlock: %d\n", depth);
+                break;
+            }
         } else if (code == ResXMLTree::START_NAMESPACE) {
             namespace_entry ns;
             size_t len;
@@ -536,7 +541,10 @@
                     ns.uri.string());
             depth++;
         } else if (code == ResXMLTree::END_NAMESPACE) {
-            depth--;
+            if (--depth < 0) {
+                printf("***BAD DEPTH in XMLBlock: %d\n", depth);
+                break;
+            }
             const namespace_entry& ns = namespaces.top();
             size_t len;
             const char16_t* prefix16 = block->getNamespacePrefix(&len);
@@ -714,7 +722,7 @@
 {
     return mFilename;
 }
-    
+
 const Vector<XMLNode::attribute_entry>&
     XMLNode::getAttributes() const
 {
@@ -730,7 +738,7 @@
             return &ae;
         }
     }
-    
+
     return NULL;
 }
 
@@ -774,14 +782,14 @@
             && mElementName == tagName) {
         return this;
     }
-    
+
     for (size_t i=0; i<mChildren.size(); i++) {
         sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName);
         if (found != NULL) {
             return found;
         }
     }
-    
+
     return NULL;
 }
 
@@ -795,7 +803,7 @@
             return child;
         }
     }
-    
+
     return NULL;
 }
 
@@ -977,7 +985,7 @@
                               ResourceTable* table)
 {
     bool hasErrors = false;
-    
+
     if (getType() == TYPE_ELEMENT) {
         const size_t N = mAttributes.size();
         String16 defPackage(assets->getPackage());
@@ -1013,7 +1021,7 @@
                                     const ResourceTable* table)
 {
     bool hasErrors = false;
-    
+
     if (getType() == TYPE_ELEMENT) {
         String16 attr("attr");
         const char* errorMsg;
@@ -1093,7 +1101,7 @@
 {
     StringPool strings(mUTF8);
     Vector<uint32_t> resids;
-    
+
     // First collect just the strings for attribute names that have a
     // resource ID assigned to them.  This ensures that the resource ID
     // array is compact, and makes it easier to deal with attribute names
@@ -1141,7 +1149,7 @@
                 dest->getSize(), (stringPool->getSize()*100)/dest->getSize(),
                 dest->getPath().string());
     }
-        
+
     return NO_ERROR;
 }
 
@@ -1217,7 +1225,7 @@
         printf("Start Namespace: %s %s\n", prefix, uri);
     }
     ParseState* st = (ParseState*)userData;
-    sp<XMLNode> node = XMLNode::newNamespace(st->filename, 
+    sp<XMLNode> node = XMLNode::newNamespace(st->filename,
             String16(prefix != NULL ? prefix : ""), String16(uri));
     node->setStartLineNumber(XML_GetCurrentLineNumber(st->parser));
     if (st->stack.size() > 0) {
@@ -1338,7 +1346,7 @@
         bool stripComments, bool stripRawValues) const
 {
     collect_attr_strings(dest, outResIds, true);
-    
+
     int i;
     if (RESOURCES_TOOLS_NAMESPACE != mNamespaceUri) {
         if (mNamespacePrefix.size() > 0) {