Merge "Add setOverlay method to QuickContactsBadge"
diff --git a/Android.mk b/Android.mk
index 852247c..232f5bf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -201,6 +201,7 @@
 	core/java/android/service/trust/ITrustAgentServiceCallback.aidl \
 	core/java/android/service/voice/IVoiceInteractionService.aidl \
 	core/java/android/service/voice/IVoiceInteractionSession.aidl \
+	core/java/android/service/voice/IVoiceInteractionSessionService.aidl \
 	core/java/android/service/wallpaper/IWallpaperConnection.aidl \
 	core/java/android/service/wallpaper/IWallpaperEngine.aidl \
 	core/java/android/service/wallpaper/IWallpaperService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 338f0c9..d4be98c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1009,6 +1009,7 @@
     field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
     field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
     field public static final int sequence = 16843815; // 0x1010427
+    field public static final int sessionService = 16843850; // 0x101044a
     field public static final int settingsActivity = 16843301; // 0x1010225
     field public static final int shadowColor = 16843105; // 0x1010161
     field public static final int shadowDx = 16843106; // 0x1010162
@@ -1104,6 +1105,7 @@
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
     field public static final int switchPreferenceStyle = 16843629; // 0x101036d
+    field public static final int switchStyle = 16843851; // 0x101044b
     field public static final int switchTextAppearance = 16843630; // 0x101036e
     field public static final int switchTextOff = 16843628; // 0x101036c
     field public static final int switchTextOn = 16843627; // 0x101036b
@@ -1663,10 +1665,14 @@
     field public static final int decelerate_cubic = 17563651; // 0x10c0003
     field public static final int decelerate_quad = 17563649; // 0x10c0001
     field public static final int decelerate_quint = 17563653; // 0x10c0005
-    field public static final int fast_out_linear_in = 17563663; // 0x10c000f
-    field public static final int fast_out_slow_in = 17563661; // 0x10c000d
+    field public static final int fast_out_linear_in = 17563667; // 0x10c0013
+    field public static final int fast_out_slow_in = 17563665; // 0x10c0011
+    field public static final int l_resource_pad1 = 17563664; // 0x10c0010
+    field public static final int l_resource_pad2 = 17563663; // 0x10c000f
+    field public static final int l_resource_pad3 = 17563662; // 0x10c000e
+    field public static final int l_resource_pad4 = 17563661; // 0x10c000d
     field public static final int linear = 17563659; // 0x10c000b
-    field public static final int linear_out_slow_in = 17563662; // 0x10c000e
+    field public static final int linear_out_slow_in = 17563666; // 0x10c0012
     field public static final int overshoot = 17563656; // 0x10c0008
   }
 
@@ -4842,20 +4848,26 @@
   }
 
   public class VoiceInteractor {
-    method public android.app.VoiceInteractor.Request startCommand(android.app.VoiceInteractor.Callback, java.lang.String, android.os.Bundle);
-    method public android.app.VoiceInteractor.Request startConfirmation(android.app.VoiceInteractor.Callback, java.lang.String, android.os.Bundle);
+    method public boolean submitRequest(android.app.VoiceInteractor.Request);
     method public boolean[] supportsCommands(java.lang.String[]);
   }
 
-  public static class VoiceInteractor.Callback {
-    ctor public VoiceInteractor.Callback();
-    method public void onCancel(android.app.VoiceInteractor.Request);
-    method public void onCommandResult(android.app.VoiceInteractor.Request, android.os.Bundle);
-    method public void onConfirmationResult(android.app.VoiceInteractor.Request, boolean, android.os.Bundle);
+  public static class VoiceInteractor.CommandRequest extends android.app.VoiceInteractor.Request {
+    ctor public VoiceInteractor.CommandRequest(java.lang.String, android.os.Bundle);
+    method public void onCommandResult(android.os.Bundle);
   }
 
-  public static class VoiceInteractor.Request {
+  public static class VoiceInteractor.ConfirmationRequest extends android.app.VoiceInteractor.Request {
+    ctor public VoiceInteractor.ConfirmationRequest(java.lang.CharSequence, android.os.Bundle);
+    method public void onConfirmationResult(boolean, android.os.Bundle);
+  }
+
+  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();
+    method public void onCancel();
   }
 
   public final class WallpaperInfo implements android.os.Parcelable {
@@ -24919,7 +24931,7 @@
   public class VoiceInteractionService extends android.app.Service {
     ctor public VoiceInteractionService();
     method public android.os.IBinder onBind(android.content.Intent);
-    method public void startVoiceActivity(android.content.Intent, android.service.voice.VoiceInteractionSession);
+    method public void startVoiceActivity(android.content.Intent, android.os.Bundle);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
     field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
   }
@@ -24938,10 +24950,16 @@
 
   public static class VoiceInteractionSession.Request {
     method public void sendCancelResult();
-    method public void sendCommandResult(android.os.Bundle);
+    method public void sendCommandResult(boolean, android.os.Bundle);
     method public void sendConfirmResult(boolean, android.os.Bundle);
   }
 
+  public abstract class VoiceInteractionSessionService extends android.app.Service {
+    ctor public VoiceInteractionSessionService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.service.voice.VoiceInteractionSession onNewSession(android.os.Bundle);
+  }
+
 }
 
 package android.service.wallpaper {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 197eaf8..8981c88 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5454,7 +5454,7 @@
         mEmbeddedID = id;
         mLastNonConfigurationInstances = lastNonConfigurationInstances;
         mVoiceInteractor = voiceInteractor != null
-                ? new VoiceInteractor(this, voiceInteractor, Looper.myLooper()) : null;
+                ? new VoiceInteractor(this, this, voiceInteractor, Looper.myLooper()) : null;
 
         mWindow.setWindowManager(
                 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fe629f6..25a1493 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -328,8 +328,8 @@
 
     /**
      * Bit to be bitwise-ored into the {@link #flags} field that should be
-     * set if you want the sound and/or vibration play each time the
-     * notification is sent, even if it has not been canceled before that.
+     * set if you would only like the sound, vibrate and ticker to be played
+     * if the notification was not already showing.
      */
     public static final int FLAG_ONLY_ALERT_ONCE    = 0x00000008;
 
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 1b838fb..4427ce1 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -19,6 +19,9 @@
 import android.content.SharedPreferences;
 import android.os.FileUtils;
 import android.os.Looper;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
 import android.util.Log;
 
 import com.google.android.collect.Maps;
@@ -43,10 +46,7 @@
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
 
-import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
-import libcore.io.StructStat;
 
 final class SharedPreferencesImpl implements SharedPreferences {
     private static final String TAG = "SharedPreferencesImpl";
@@ -110,7 +110,7 @@
         Map map = null;
         StructStat stat = null;
         try {
-            stat = Libcore.os.stat(mFile.getPath());
+            stat = Os.stat(mFile.getPath());
             if (mFile.canRead()) {
                 BufferedInputStream str = null;
                 try {
@@ -172,7 +172,7 @@
              * violation, but we explicitly want this one.
              */
             BlockGuard.getThreadPolicy().onReadFromDisk();
-            stat = Libcore.os.stat(mFile.getPath());
+            stat = Os.stat(mFile.getPath());
         } catch (ErrnoException e) {
             return true;
         }
@@ -599,7 +599,7 @@
             str.close();
             ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
             try {
-                final StructStat stat = Libcore.os.stat(mFile.getPath());
+                final StructStat stat = Os.stat(mFile.getPath());
                 synchronized (this) {
                     mStatTimestamp = stat.st_mtime;
                     mStatSize = stat.st_size;
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 6820dfd..6dc48b0 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -22,6 +22,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.util.ArrayMap;
 import android.util.Log;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.IVoiceInteractorCallback;
@@ -39,50 +40,85 @@
     static final boolean DEBUG = true;
 
     final Context mContext;
+    final Activity mActivity;
     final IVoiceInteractor mInteractor;
     final HandlerCaller mHandlerCaller;
     final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() {
         @Override
         public void executeMessage(Message msg) {
             SomeArgs args = (SomeArgs)msg.obj;
+            Request request;
             switch (msg.what) {
                 case MSG_CONFIRMATION_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                     if (DEBUG) Log.d(TAG, "onConfirmResult: req="
-                            + ((IVoiceInteractorRequest)args.arg2).asBinder()
-                            + " confirmed=" + msg.arg1 + " result=" + args.arg3);
-                    ((Callback)args.arg1).onConfirmationResult(
-                            findRequest((IVoiceInteractorRequest)args.arg2),
-                            msg.arg1 != 0, (Bundle)args.arg3);
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+                            + " confirmed=" + msg.arg1 + " result=" + args.arg2);
+                    if (request != null) {
+                        ((ConfirmationRequest)request).onConfirmationResult(msg.arg1 != 0,
+                                (Bundle) args.arg2);
+                        request.clear();
+                    }
                     break;
                 case MSG_COMMAND_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, msg.arg1 != 0);
                     if (DEBUG) Log.d(TAG, "onCommandResult: req="
-                            + ((IVoiceInteractorRequest)args.arg2).asBinder()
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
                             + " result=" + args.arg2);
-                    ((Callback)args.arg1).onCommandResult(
-                            findRequest((IVoiceInteractorRequest) args.arg2),
-                            (Bundle) args.arg3);
+                    if (request != null) {
+                        ((CommandRequest)request).onCommandResult((Bundle) args.arg2);
+                        if (msg.arg1 != 0) {
+                            request.clear();
+                        }
+                    }
                     break;
                 case MSG_CANCEL_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
                     if (DEBUG) Log.d(TAG, "onCancelResult: req="
-                            + ((IVoiceInteractorRequest)args.arg2).asBinder());
-                    ((Callback)args.arg1).onCancel(
-                            findRequest((IVoiceInteractorRequest) args.arg2));
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request);
+                    if (request != null) {
+                        request.onCancel();
+                        request.clear();
+                    }
                     break;
             }
         }
     };
 
-    final WeakHashMap<IBinder, Request> mActiveRequests = new WeakHashMap<IBinder, Request>();
+    final IVoiceInteractorCallback.Stub mCallback = new IVoiceInteractorCallback.Stub() {
+        @Override
+        public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
+                Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
+                    MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, request, result));
+        }
+
+        @Override
+        public void deliverCommandResult(IVoiceInteractorRequest request, boolean complete,
+                Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
+                    MSG_COMMAND_RESULT, complete ? 1 : 0, request, result));
+        }
+
+        @Override
+        public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(
+                    MSG_CANCEL_RESULT, request));
+        }
+    };
+
+    final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
 
     static final int MSG_CONFIRMATION_RESULT = 1;
     static final int MSG_COMMAND_RESULT = 2;
     static final int MSG_CANCEL_RESULT = 3;
 
-    public static class Request {
-        final IVoiceInteractorRequest mRequestInterface;
+    public static abstract class Request {
+        IVoiceInteractorRequest mRequestInterface;
+        Context mContext;
+        Activity mActivity;
 
-        Request(IVoiceInteractorRequest requestInterface) {
-            mRequestInterface = requestInterface;
+        public Request() {
         }
 
         public void cancel() {
@@ -92,126 +128,130 @@
                 Log.w(TAG, "Voice interactor has died", e);
             }
         }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public Activity getActivity() {
+            return mActivity;
+        }
+
+        public void onCancel() {
+        }
+
+        void clear() {
+            mRequestInterface = null;
+            mContext = null;
+            mActivity = null;
+        }
+
+        abstract IVoiceInteractorRequest submit(IVoiceInteractor interactor,
+                String packageName, IVoiceInteractorCallback callback) throws RemoteException;
     }
 
-    public static class Callback {
-        VoiceInteractor mInteractor;
+    public static class ConfirmationRequest extends Request {
+        final CharSequence mPrompt;
+        final Bundle mExtras;
 
-        final IVoiceInteractorCallback.Stub mWrapper = new IVoiceInteractorCallback.Stub() {
-            @Override
-            public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
-                    Bundle result) {
-                mInteractor.mHandlerCaller.sendMessage(mInteractor.mHandlerCaller.obtainMessageIOOO(
-                        MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, Callback.this, request,
-                        result));
-            }
-
-            @Override
-            public void deliverCommandResult(IVoiceInteractorRequest request, Bundle result) {
-                mInteractor.mHandlerCaller.sendMessage(mInteractor.mHandlerCaller.obtainMessageOOO(
-                        MSG_COMMAND_RESULT, Callback.this, request, result));
-            }
-
-            @Override
-            public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException {
-                mInteractor.mHandlerCaller.sendMessage(mInteractor.mHandlerCaller.obtainMessageOO(
-                        MSG_CANCEL_RESULT, Callback.this, request));
-            }
-        };
-
-        public void onConfirmationResult(Request request, boolean confirmed, Bundle result) {
+        /**
+         * 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.
+         * @param prompt Optional confirmation text to read to the user as the action being
+         * confirmed.
+         * @param extras Additional optional information.
+         */
+        public ConfirmationRequest(CharSequence prompt, Bundle extras) {
+            mPrompt = prompt;
+            mExtras = extras;
         }
 
-        public void onCommandResult(Request request, Bundle result) {
+        public void onConfirmationResult(boolean confirmed, Bundle result) {
         }
 
-        public void onCancel(Request request) {
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startConfirmation(packageName, callback, mPrompt.toString(), mExtras);
         }
-    }
+   }
 
-    VoiceInteractor(Context context, IVoiceInteractor interactor, Looper looper) {
+    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(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.)
+         *
+         * @param command The desired command to perform.
+         * @param args Additional arguments to control execution of the command.
+         */
+        public CommandRequest(String command, Bundle args) {
+            mCommand = command;
+            mArgs = args;
+        }
+
+        public void onCommandResult(Bundle result) {
+        }
+
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startConfirmation(packageName, callback, mCommand, mArgs);
+        }
+   }
+
+    VoiceInteractor(Context context, Activity activity, IVoiceInteractor interactor,
+            Looper looper) {
         mContext = context;
+        mActivity = activity;
         mInteractor = interactor;
         mHandlerCaller = new HandlerCaller(context, looper, mHandlerCallerCallback, true);
     }
 
-    Request storeRequest(IVoiceInteractorRequest request) {
-        synchronized (mActiveRequests) {
-            Request req = new Request(request);
-            mActiveRequests.put(request.asBinder(), req);
-            return req;
-        }
-    }
-
-    Request findRequest(IVoiceInteractorRequest request) {
+    Request pullRequest(IVoiceInteractorRequest request, boolean complete) {
         synchronized (mActiveRequests) {
             Request req = mActiveRequests.get(request.asBinder());
-            if (req == null) {
-                throw new IllegalStateException("Received callback without active request: "
-                        + request);
+            if (req != null && complete) {
+                mActiveRequests.remove(request.asBinder());
             }
             return req;
         }
     }
 
-    /**
-     * Asynchronously 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 by calling the
-     * {@link Callback#onConfirmationResult Callback.onConfirmationResult} method.
-     *
-     * 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 informed consent.
-     * @param callback Required callback target for interaction results.
-     * @param prompt Optional confirmation text to read to the user as the action being confirmed.
-     * @param extras Additional optional information.
-     * @return Returns a new {@link Request} object representing this operation.
-     */
-    public Request startConfirmation(Callback callback, String prompt, Bundle extras) {
+    public boolean submitRequest(Request request) {
         try {
-            callback.mInteractor = this;
-            Request req = storeRequest(mInteractor.startConfirmation(
-                    mContext.getOpPackageName(), callback.mWrapper, prompt, extras));
-            if (DEBUG) Log.d(TAG, "startConfirmation: req=" + req.mRequestInterface.asBinder()
-                    + " prompt=" + prompt + " extras=" + extras);
-            return req;
+            IVoiceInteractorRequest ireq = request.submit(mInteractor,
+                    mContext.getOpPackageName(), mCallback);
+            request.mRequestInterface = ireq;
+            request.mContext = mContext;
+            request.mActivity = mActivity;
+            synchronized (mActiveRequests) {
+                mActiveRequests.put(ireq.asBinder(), request);
+            }
+            return true;
         } catch (RemoteException e) {
-            throw new RuntimeException("Voice interactor has died", e);
-        }
-    }
-
-    /**
-     * Asynchronously executes 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 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.)
-     * The result of the command will be returned by calling the
-     * {@link Callback#onCommandResult Callback.onCommandResult} method.
-     *
-     * @param callback Required callback target for interaction results.
-     * @param command
-     * @param extras
-     * @return Returns a new {@link Request} object representing this operation.
-     */
-    public Request startCommand(Callback callback, String command, Bundle extras) {
-        try {
-            callback.mInteractor = this;
-            Request req = storeRequest(mInteractor.startCommand(
-                    mContext.getOpPackageName(), callback.mWrapper, command, extras));
-            if (DEBUG) Log.d(TAG, "startCommand: req=" + req.mRequestInterface.asBinder()
-                    + " command=" + command + " extras=" + extras);
-            return req;
-        } catch (RemoteException e) {
-            throw new RuntimeException("Voice interactor has died", e);
+            Log.w(TAG, "Remove voice interactor service died", e);
+            return false;
         }
     }
 
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index f08097b..5f8ebbe 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -279,13 +279,15 @@
         }
 
         private Bitmap getCurrentWallpaperLocked(Context context) {
+            if (mService == null) {
+                Log.w(TAG, "WallpaperService not running");
+                return null;
+            }
+
             try {
                 Bundle params = new Bundle();
                 ParcelFileDescriptor fd = mService.getWallpaper(this, params);
                 if (fd != null) {
-                    int width = params.getInt("width", 0);
-                    int height = params.getInt("height", 0);
-
                     try {
                         BitmapFactory.Options options = new BitmapFactory.Options();
                         return BitmapFactory.decodeFileDescriptor(
@@ -307,27 +309,20 @@
         }
         
         private Bitmap getDefaultWallpaperLocked(Context context) {
-            try {
-                InputStream is = openDefaultWallpaper(context);
-                if (is != null) {
-                    int width = mService.getWidthHint();
-                    int height = mService.getHeightHint();
-
+            InputStream is = openDefaultWallpaper(context);
+            if (is != null) {
+                try {
+                    BitmapFactory.Options options = new BitmapFactory.Options();
+                    return BitmapFactory.decodeStream(is, null, options);
+                } catch (OutOfMemoryError e) {
+                    Log.w(TAG, "Can't decode stream", e);
+                } finally {
                     try {
-                        BitmapFactory.Options options = new BitmapFactory.Options();
-                        return BitmapFactory.decodeStream(is, null, options);
-                    } catch (OutOfMemoryError e) {
-                        Log.w(TAG, "Can't decode stream", e);
-                    } finally {
-                        try {
-                            is.close();
-                        } catch (IOException e) {
-                            // Ignore
-                        }
+                        is.close();
+                    } catch (IOException e) {
+                        // Ignore
                     }
                 }
-            } catch (RemoteException e) {
-                // Ignore
             }
             return null;
         }
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 3c31f8d..886f1a6 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -29,6 +29,10 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
 import android.util.Log;
 
 import java.io.File;
@@ -38,11 +42,6 @@
 import java.util.LinkedList;
 import java.util.concurrent.CountDownLatch;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.OsConstants;
-import libcore.io.StructStat;
-
 /**
  * Provides the central interface between an
  * application and Android's data backup infrastructure.  An application that wishes
@@ -195,7 +194,7 @@
      * the key supplied as part of the entity.  Writing an entity with a negative
      * data size instructs the transport to delete whatever entity currently exists
      * under that key from the remote data set.
-     * 
+     *
      * @param oldState An open, read-only ParcelFileDescriptor pointing to the
      *            last backup state provided by the application. May be
      *            <code>null</code>, in which case no prior state is being
@@ -226,7 +225,7 @@
      * onRestore() throws an exception, the OS will assume that the
      * application's data may now be in an incoherent state, and will clear it
      * before proceeding.
-     * 
+     *
      * @param data A structured wrapper around an open, read-only
      *            file descriptor pointing to a full snapshot of the
      *            application's data.  The application should consume every
@@ -416,7 +415,7 @@
                     }
 
                     // If it's a directory, enqueue its contents for scanning.
-                    StructStat stat = Libcore.os.lstat(filePath);
+                    StructStat stat = Os.lstat(filePath);
                     if (OsConstants.S_ISLNK(stat.st_mode)) {
                         if (DEBUG) Log.i(TAG, "Symlink (skipping)!: " + file);
                         continue;
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index cfd0a65..6ebb6c4 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -17,6 +17,8 @@
 package android.app.backup;
 
 import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.util.Log;
 
 import java.io.File;
@@ -24,9 +26,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-
 /**
  * Global constant definitions et cetera related to the full-backup-to-fd
  * binary format.  Nothing in this namespace is part of any API; it's all
@@ -147,7 +146,7 @@
             try {
                 // explicitly prevent emplacement of files accessible by outside apps
                 mode &= 0700;
-                Libcore.os.chmod(outFile.getPath(), (int)mode);
+                Os.chmod(outFile.getPath(), (int)mode);
             } catch (ErrnoException e) {
                 e.rethrowAsIOException();
             }
diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java
index cece556..e24aeb2 100644
--- a/core/java/android/ddm/DdmHandleHeap.java
+++ b/core/java/android/ddm/DdmHandleHeap.java
@@ -219,7 +219,7 @@
 
         if (false)
             Log.d("ddm-heap", "Heap GC request");
-        System.gc();
+        Runtime.getRuntime().gc();
 
         return null;        // empty response
     }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c51d1a7..505ef9c 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -255,7 +255,9 @@
     public static final int CURSOR_ANCHOR_MONITOR_MODE_NONE = 0x0;
 
     /**
-     * The IME expects that {@link #onUpdateCursor(Rect)} is called back.
+     * Passing this flag into a call to {@link #setCursorAnchorMonitorMode(int)} will result in
+     * the cursor rectangle being provided in screen coordinates to subsequent
+     * {@link #onUpdateCursor(Rect)} callbacks.
      */
     public static final int CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT = 0x1;
 
@@ -1703,9 +1705,11 @@
     }
 
     /**
-     * Called when the application has reported a new location of its text
-     * cursor.  This is only called if explicitly requested by the input method.
-     * The default implementation does nothing.
+     * Called when the application has reported a new location of its text cursor.  This is only
+     * called if explicitly requested by the input method.  The default implementation does nothing.
+     * @param newCursor The new cursor position, in screen coordinates if the input method calls
+     * {@link #setCursorAnchorMonitorMode} with {@link #CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT}.
+     * Otherwise, this is in local coordinates.
      */
     public void onUpdateCursor(Rect newCursor) {
         // Intentionally empty
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index 22543e3..a725bec 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -24,13 +24,13 @@
 import java.net.InterfaceAddress;
 import java.net.UnknownHostException;
 
-import static libcore.io.OsConstants.IFA_F_DADFAILED;
-import static libcore.io.OsConstants.IFA_F_DEPRECATED;
-import static libcore.io.OsConstants.IFA_F_TENTATIVE;
-import static libcore.io.OsConstants.RT_SCOPE_HOST;
-import static libcore.io.OsConstants.RT_SCOPE_LINK;
-import static libcore.io.OsConstants.RT_SCOPE_SITE;
-import static libcore.io.OsConstants.RT_SCOPE_UNIVERSE;
+import static android.system.OsConstants.IFA_F_DADFAILED;
+import static android.system.OsConstants.IFA_F_DEPRECATED;
+import static android.system.OsConstants.IFA_F_TENTATIVE;
+import static android.system.OsConstants.RT_SCOPE_HOST;
+import static android.system.OsConstants.RT_SCOPE_LINK;
+import static android.system.OsConstants.RT_SCOPE_SITE;
+import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
 /**
  * Identifies an IP address on a network link.
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index 119e533..643e8c2 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -22,9 +22,9 @@
 import java.io.FileDescriptor;
 import java.net.SocketOptions;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.OsConstants;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 
 /**
  * Socket implementation used for android.net.LocalSocket and
@@ -248,7 +248,7 @@
                     throw new IllegalStateException("unknown sockType");
             }
             try {
-                fd = Libcore.os.socket(OsConstants.AF_UNIX, osType, 0);
+                fd = Os.socket(OsConstants.AF_UNIX, osType, 0);
                 mFdCreatedInternally = true;
             } catch (ErrnoException e) {
                 e.rethrowAsIOException();
@@ -268,7 +268,7 @@
                 return;
             }
             try {
-                Libcore.os.close(fd);
+                Os.close(fd);
             } catch (ErrnoException e) {
                 e.rethrowAsIOException();
             }
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
index 2ecf317..f83a90b 100644
--- a/core/java/android/os/CommonClock.java
+++ b/core/java/android/os/CommonClock.java
@@ -23,6 +23,7 @@
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import static android.system.OsConstants.*;
 
 /**
  * Used for accessing the android common time service's common clock and receiving notifications
diff --git a/core/java/android/os/CommonTimeUtils.java b/core/java/android/os/CommonTimeUtils.java
index 20755d9..ba060b8 100644
--- a/core/java/android/os/CommonTimeUtils.java
+++ b/core/java/android/os/CommonTimeUtils.java
@@ -20,7 +20,7 @@
 import java.net.Inet6Address;
 import java.net.InetSocketAddress;
 import java.util.Locale;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
 
 class CommonTimeUtils {
     /**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 1089f27..d71c3e6 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,12 +16,12 @@
 
 package android.os;
 
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 import android.util.Log;
 import android.util.Slog;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -85,7 +85,7 @@
      */
     public static int setPermissions(String path, int mode, int uid, int gid) {
         try {
-            Libcore.os.chmod(path, mode);
+            Os.chmod(path, mode);
         } catch (ErrnoException e) {
             Slog.w(TAG, "Failed to chmod(" + path + "): " + e);
             return e.errno;
@@ -93,7 +93,7 @@
 
         if (uid >= 0 || gid >= 0) {
             try {
-                Libcore.os.chown(path, uid, gid);
+                Os.chown(path, uid, gid);
             } catch (ErrnoException e) {
                 Slog.w(TAG, "Failed to chown(" + path + "): " + e);
                 return e.errno;
@@ -113,7 +113,7 @@
      */
     public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) {
         try {
-            Libcore.os.fchmod(fd, mode);
+            Os.fchmod(fd, mode);
         } catch (ErrnoException e) {
             Slog.w(TAG, "Failed to fchmod(): " + e);
             return e.errno;
@@ -121,7 +121,7 @@
 
         if (uid >= 0 || gid >= 0) {
             try {
-                Libcore.os.fchown(fd, uid, gid);
+                Os.fchown(fd, uid, gid);
             } catch (ErrnoException e) {
                 Slog.w(TAG, "Failed to fchown(): " + e);
                 return e.errno;
@@ -136,7 +136,7 @@
      */
     public static int getUid(String path) {
         try {
-            return Libcore.os.stat(path).st_uid;
+            return Os.stat(path).st_uid;
         } catch (ErrnoException e) {
             return -1;
         }
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 24bf05e..c6b2151 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -16,24 +16,24 @@
 
 package android.os;
 
-import static libcore.io.OsConstants.AF_UNIX;
-import static libcore.io.OsConstants.SEEK_SET;
-import static libcore.io.OsConstants.SOCK_STREAM;
-import static libcore.io.OsConstants.S_ISLNK;
-import static libcore.io.OsConstants.S_ISREG;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.SEEK_SET;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.S_ISLNK;
+import static android.system.OsConstants.S_ISREG;
 
 import android.content.BroadcastReceiver;
 import android.content.ContentProvider;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
 import android.util.Log;
 
 import dalvik.system.CloseGuard;
 
-import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 import libcore.io.Memory;
-import libcore.io.OsConstants;
-import libcore.io.StructStat;
 
 import java.io.Closeable;
 import java.io.File;
@@ -261,7 +261,7 @@
      */
     public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException {
         try {
-            final FileDescriptor fd = Libcore.os.dup(orig);
+            final FileDescriptor fd = Os.dup(orig);
             return new ParcelFileDescriptor(fd);
         } catch (ErrnoException e) {
             throw e.rethrowAsIOException();
@@ -297,7 +297,7 @@
         original.setInt$(fd);
 
         try {
-            final FileDescriptor dup = Libcore.os.dup(original);
+            final FileDescriptor dup = Os.dup(original);
             return new ParcelFileDescriptor(dup);
         } catch (ErrnoException e) {
             throw e.rethrowAsIOException();
@@ -359,7 +359,7 @@
      */
     public static ParcelFileDescriptor[] createPipe() throws IOException {
         try {
-            final FileDescriptor[] fds = Libcore.os.pipe();
+            final FileDescriptor[] fds = Os.pipe();
             return new ParcelFileDescriptor[] {
                     new ParcelFileDescriptor(fds[0]),
                     new ParcelFileDescriptor(fds[1]) };
@@ -381,7 +381,7 @@
     public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
         try {
             final FileDescriptor[] comm = createCommSocketPair();
-            final FileDescriptor[] fds = Libcore.os.pipe();
+            final FileDescriptor[] fds = Os.pipe();
             return new ParcelFileDescriptor[] {
                     new ParcelFileDescriptor(fds[0], comm[0]),
                     new ParcelFileDescriptor(fds[1], comm[1]) };
@@ -398,7 +398,7 @@
         try {
             final FileDescriptor fd0 = new FileDescriptor();
             final FileDescriptor fd1 = new FileDescriptor();
-            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
             return new ParcelFileDescriptor[] {
                     new ParcelFileDescriptor(fd0),
                     new ParcelFileDescriptor(fd1) };
@@ -421,7 +421,7 @@
             final FileDescriptor[] comm = createCommSocketPair();
             final FileDescriptor fd0 = new FileDescriptor();
             final FileDescriptor fd1 = new FileDescriptor();
-            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
             return new ParcelFileDescriptor[] {
                     new ParcelFileDescriptor(fd0, comm[0]),
                     new ParcelFileDescriptor(fd1, comm[1]) };
@@ -434,7 +434,7 @@
         try {
             final FileDescriptor comm1 = new FileDescriptor();
             final FileDescriptor comm2 = new FileDescriptor();
-            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
+            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
             IoUtils.setBlocking(comm1, false);
             IoUtils.setBlocking(comm2, false);
             return new FileDescriptor[] { comm1, comm2 };
@@ -520,7 +520,7 @@
             return mWrapped.getStatSize();
         } else {
             try {
-                final StructStat st = Libcore.os.fstat(mFd);
+                final StructStat st = Os.fstat(mFd);
                 if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
                     return st.st_size;
                 } else {
@@ -543,7 +543,7 @@
             return mWrapped.seekTo(pos);
         } else {
             try {
-                return Libcore.os.lseek(mFd, pos, SEEK_SET);
+                return Os.lseek(mFd, pos, SEEK_SET);
             } catch (ErrnoException e) {
                 throw e.rethrowAsIOException();
             }
@@ -695,7 +695,7 @@
                     writePtr += len;
                 }
 
-                Libcore.os.write(mCommFd, buf, 0, writePtr);
+                Os.write(mCommFd, buf, 0, writePtr);
             } catch (ErrnoException e) {
                 // Reporting status is best-effort
                 Log.w(TAG, "Failed to report status: " + e);
@@ -712,7 +712,7 @@
 
     private static Status readCommStatus(FileDescriptor comm, byte[] buf) {
         try {
-            final int n = Libcore.os.read(comm, buf, 0, buf.length);
+            final int n = Os.read(comm, buf, 0, buf.length);
             if (n == 0) {
                 // EOF means they're dead
                 return new Status(Status.DEAD);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 995e396..b4ed68c 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -18,6 +18,7 @@
 
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
+import android.system.Os;
 import android.util.Log;
 import com.android.internal.os.Zygote;
 import java.io.BufferedWriter;
@@ -28,7 +29,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import libcore.io.Libcore;
 
 /*package*/ class ZygoteStartFailedEx extends Exception {
     /**
@@ -741,7 +741,7 @@
      * {@link #killProcess} and {@link #sendSignal}.
      */
     public static final int myPid() {
-        return Libcore.os.getpid();
+        return Os.getpid();
     }
 
     /**
@@ -749,7 +749,7 @@
      * @hide
      */
     public static final int myPpid() {
-        return Libcore.os.getppid();
+        return Os.getppid();
     }
 
     /**
@@ -757,7 +757,7 @@
      * {@link #setThreadPriority(int, int)}.
      */
     public static final int myTid() {
-        return Libcore.os.gettid();
+        return Os.gettid();
     }
 
     /**
@@ -767,7 +767,7 @@
      * a uid identifies a specific app sandbox in a specific user.
      */
     public static final int myUid() {
-        return Libcore.os.getuid();
+        return Os.getuid();
     }
 
     /**
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 9e9521a..13e9a15 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,9 +16,9 @@
 
 package android.os;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.StructStatVfs;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStatVfs;
 
 /**
  * Retrieve overall information about the space on a filesystem. This is a
@@ -41,7 +41,7 @@
 
     private static StructStatVfs doStat(String path) {
         try {
-            return Libcore.os.statvfs(path);
+            return Os.statvfs(path);
         } catch (ErrnoException e) {
             throw new IllegalArgumentException("Invalid path: " + path, e);
         }
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 9a768e0..b907375 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -17,7 +17,7 @@
 package android.provider;
 
 import static android.net.TrafficStats.KB_IN_BYTES;
-import static libcore.io.OsConstants.SEEK_SET;
+import static android.system.OsConstants.SEEK_SET;
 
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -38,11 +38,11 @@
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelFileDescriptor.OnCloseListener;
 import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.util.Log;
 
-import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.BufferedInputStream;
 import java.io.File;
@@ -809,7 +809,7 @@
             // optimal decode path; otherwise fall back to buffering.
             BufferedInputStream is = null;
             try {
-                Libcore.os.lseek(fd, offset, SEEK_SET);
+                Os.lseek(fd, offset, SEEK_SET);
             } catch (ErrnoException e) {
                 is = new BufferedInputStream(new FileInputStream(fd), THUMBNAIL_BUFFER_SIZE);
                 is.mark(THUMBNAIL_BUFFER_SIZE);
@@ -835,7 +835,7 @@
                 bitmap = BitmapFactory.decodeStream(is, null, opts);
             } else {
                 try {
-                    Libcore.os.lseek(fd, offset, SEEK_SET);
+                    Os.lseek(fd, offset, SEEK_SET);
                 } catch (ErrnoException e) {
                     e.rethrowAsIOException();
                 }
diff --git a/core/java/android/service/voice/IVoiceInteractionSessionService.aidl b/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
new file mode 100644
index 0000000..2519442
--- /dev/null
+++ b/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.service.voice;
+
+import android.os.Bundle;
+
+import android.service.voice.IVoiceInteractionSession;
+
+/**
+ * @hide
+ */
+oneway interface IVoiceInteractionSessionService {
+    void newSession(IBinder token, in Bundle args);
+}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index ed93b74..d005890 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -21,6 +21,7 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -50,12 +51,11 @@
 
     IVoiceInteractionManagerService mSystemService;
 
-    public void startVoiceActivity(Intent intent, VoiceInteractionSession session) {
+    public void startVoiceActivity(Intent intent, Bundle sessionArgs) {
         try {
-            int res = mSystemService.startVoiceActivity(intent,
+            mSystemService.startVoiceActivity(intent,
                     intent.resolveType(getContentResolver()),
-                    mInterface, session.mSession, session.mInteractor);
-            Instrumentation.checkStartActivityResult(res, intent);
+                    mInterface, sessionArgs);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
new file mode 100644
index 0000000..a909ead
--- /dev/null
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 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.service.voice;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.speech.RecognitionService;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/** @hide */
+public class VoiceInteractionServiceInfo {
+    static final String TAG = "VoiceInteractionServiceInfo";
+
+    private String mParseError;
+
+    private ServiceInfo mServiceInfo;
+    private String mSessionService;
+    private String mSettingsActivity;
+
+    public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp)
+            throws PackageManager.NameNotFoundException {
+        this(pm, pm.getServiceInfo(comp, PackageManager.GET_META_DATA));
+    }
+
+    public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
+        if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
+            mParseError = "Service does not require permission "
+                    + Manifest.permission.BIND_VOICE_INTERACTION;
+            return;
+        }
+
+        XmlResourceParser parser = null;
+        try {
+            parser = si.loadXmlMetaData(pm, VoiceInteractionService.SERVICE_META_DATA);
+            if (parser == null) {
+                mParseError = "No " + VoiceInteractionService.SERVICE_META_DATA
+                        + " meta-data for " + si.packageName;
+                return;
+            }
+
+            Resources res = pm.getResourcesForApplication(si.applicationInfo);
+
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+
+            int type;
+            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+                    && type != XmlPullParser.START_TAG) {
+            }
+
+            String nodeName = parser.getName();
+            if (!"voice-interaction-service".equals(nodeName)) {
+                mParseError = "Meta-data does not start with voice-interaction-service tag";
+                return;
+            }
+
+            TypedArray array = res.obtainAttributes(attrs,
+                    com.android.internal.R.styleable.VoiceInteractionService);
+            mSessionService = array.getString(
+                    com.android.internal.R.styleable.VoiceInteractionService_sessionService);
+            mSettingsActivity = array.getString(
+                    com.android.internal.R.styleable.VoiceInteractionService_settingsActivity);
+            array.recycle();
+            if (mSessionService == null) {
+                mParseError = "No sessionService specified";
+                return;
+            }
+        } catch (XmlPullParserException e) {
+            mParseError = "Error parsing voice interation service meta-data: " + e;
+            Log.w(TAG, "error parsing voice interaction service meta-data", e);
+            return;
+        } catch (IOException e) {
+            mParseError = "Error parsing voice interation service meta-data: " + e;
+            Log.w(TAG, "error parsing voice interaction service meta-data", e);
+            return;
+        } catch (PackageManager.NameNotFoundException e) {
+            mParseError = "Error parsing voice interation service meta-data: " + e;
+            Log.w(TAG, "error parsing voice interaction service meta-data", e);
+            return;
+        } finally {
+            if (parser != null) parser.close();
+        }
+        mServiceInfo = si;
+    }
+
+    public String getParseError() {
+        return mParseError;
+    }
+
+    public ServiceInfo getServiceInfo() {
+        return mServiceInfo;
+    }
+
+    public String getSessionService() {
+        return mSessionService;
+    }
+
+    public String getSettingsActivity() {
+        return mSettingsActivity;
+    }
+}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 59544be..963b6b4 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -96,11 +96,11 @@
             }
         }
 
-        public void sendCommandResult(Bundle result) {
+        public void sendCommandResult(boolean complete, Bundle result) {
             try {
                 if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface
                         + " result=" + result);
-                mCallback.deliverCommandResult(mInterface, result);
+                mCallback.deliverCommandResult(mInterface, complete, result);
             } catch (RemoteException e) {
             }
         }
diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java
new file mode 100644
index 0000000..40e5bba
--- /dev/null
+++ b/core/java/android/service/voice/VoiceInteractionSessionService.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2014 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.service.voice;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import com.android.internal.app.IVoiceInteractionManagerService;
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+
+public abstract class VoiceInteractionSessionService extends Service {
+
+    static final int MSG_NEW_SESSION = 1;
+
+    IVoiceInteractionManagerService mSystemService;
+
+    IVoiceInteractionSessionService mInterface = new IVoiceInteractionSessionService.Stub() {
+        public void newSession(IBinder token, Bundle args) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(MSG_NEW_SESSION,
+                    token, args));
+
+        }
+    };
+
+    HandlerCaller mHandlerCaller;
+    final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() {
+        @Override
+        public void executeMessage(Message msg) {
+            SomeArgs args = (SomeArgs)msg.obj;
+            switch (msg.what) {
+                case MSG_NEW_SESSION:
+                    doNewSession((IBinder)args.arg1, (Bundle)args.arg2);
+                    break;
+            }
+        }
+    };
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mSystemService = IVoiceInteractionManagerService.Stub.asInterface(
+                ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
+        mHandlerCaller = new HandlerCaller(this, Looper.myLooper(),
+                mHandlerCallerCallback, true);
+    }
+
+    public abstract VoiceInteractionSession onNewSession(Bundle args);
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mInterface.asBinder();
+    }
+
+    void doNewSession(IBinder token, Bundle args) {
+        VoiceInteractionSession session = onNewSession(args);
+        try {
+            mSystemService.deliverNewSession(token, session.mSession, session.mInteractor);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index d8d11f7..97339cc 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -555,7 +555,7 @@
     }
 
     @Override
-    public void invokeFunctor(long functor, boolean waitForCompletion) {
+    void invokeFunctor(long functor, boolean waitForCompletion) {
         boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
         boolean hasContext = !needsContext;
 
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 56d96e1..d31c79d 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -453,7 +453,7 @@
      *                          has invoked. If false, the functor may be invoked
      *                          asynchronously.
      */
-    public abstract void invokeFunctor(long functor, boolean waitForCompletion);
+    abstract void invokeFunctor(long functor, boolean waitForCompletion);
 
     /**
      * Initializes the hardware renderer for the specified surface and setup the
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 924c331..c7a6d41 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -217,7 +217,7 @@
     }
 
     @Override
-    public void invokeFunctor(long functor, boolean waitForCompletion) {
+    void invokeFunctor(long functor, boolean waitForCompletion) {
         nInvokeFunctor(mNativeProxy, functor, waitForCompletion);
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 246905d..5a48a9a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -678,6 +678,14 @@
         }
     }
 
+    public boolean invokeFunctor(long functor, boolean waitForCompletion) {
+        if (mAttachInfo.mHardwareRenderer == null || !mAttachInfo.mHardwareRenderer.isEnabled()) {
+            return false;
+        }
+        mAttachInfo.mHardwareRenderer.invokeFunctor(functor, waitForCompletion);
+        return true;
+    }
+
     private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
         mAttachInfo.mHardwareAccelerated = false;
         mAttachInfo.mHardwareAccelerationRequested = false;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e3bd9fd..0227873 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -317,6 +317,10 @@
     int mCursorSelEnd;
     int mCursorCandStart;
     int mCursorCandEnd;
+    /**
+     * The buffer to retrieve the view location in screen coordinates in {@link #updateCursor}.
+     */
+    private final int[] mViewTopLeft = new int[2];
 
     // -----------------------------------------------------------
     
@@ -1487,12 +1491,26 @@
             return false;
         }
         synchronized (mH) {
-            return mCursorAnchorMonitorMode ==
-                    InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT;
+            return (mCursorAnchorMonitorMode &
+                    InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT) != 0;
         }
     }
 
     /**
+     * Returns true if the current input method wants to receive the cursor rectangle in
+     * screen coordinates rather than local coordinates in the attached view.
+     *
+     * @hide
+     */
+    public boolean usesScreenCoordinatesForCursorLocked() {
+        // {@link InputMethodService#CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT} also means
+        // that {@link InputMethodService#onUpdateCursor} should provide the cursor rectangle
+        // in screen coordinates rather than local coordinates.
+        return (mCursorAnchorMonitorMode &
+                InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT) != 0;
+    }
+
+    /**
      * Set cursor/anchor monitor mode via {@link com.android.server.InputMethodManagerService}.
      * This is an internal method for {@link android.inputmethodservice.InputMethodService} and
      * should never be used from IMEs and applications.
@@ -1518,15 +1536,18 @@
                     || mCurrentTextBoxAttribute == null || mCurMethod == null) {
                 return;
             }
-            
             mTmpCursorRect.set(left, top, right, bottom);
             if (!mCursorRect.equals(mTmpCursorRect)) {
                 if (DEBUG) Log.d(TAG, "updateCursor");
 
                 try {
                     if (DEBUG) Log.v(TAG, "CURSOR CHANGE: " + mCurMethod);
-                    mCurMethod.updateCursor(mTmpCursorRect);
                     mCursorRect.set(mTmpCursorRect);
+                    if (usesScreenCoordinatesForCursorLocked()) {
+                        view.getLocationOnScreen(mViewTopLeft);
+                        mTmpCursorRect.offset(mViewTopLeft[0], mViewTopLeft[1]);
+                    }
+                    mCurMethod.updateCursor(mTmpCursorRect);
                 } catch (RemoteException e) {
                     Log.w(TAG, "IME died: " + mCurId, e);
                 }
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index e3c0728..3219ddd 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -17,12 +17,15 @@
 package com.android.internal.app;
 
 import android.content.Intent;
+import android.os.Bundle;
 
 import com.android.internal.app.IVoiceInteractor;
 import android.service.voice.IVoiceInteractionService;
 import android.service.voice.IVoiceInteractionSession;
 
 interface IVoiceInteractionManagerService {
-    int startVoiceActivity(in Intent intent, String resolvedType, IVoiceInteractionService service,
-            IVoiceInteractionSession session, IVoiceInteractor interactor);
+    void startVoiceActivity(in Intent intent, String resolvedType, IVoiceInteractionService service,
+            in Bundle sessionArgs);
+    int deliverNewSession(IBinder token, IVoiceInteractionSession session,
+            IVoiceInteractor interactor);
 }
diff --git a/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl b/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
index f5392e9..c6f93e1 100644
--- a/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractorCallback.aidl
@@ -26,6 +26,6 @@
 oneway interface IVoiceInteractorCallback {
     void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
             in Bundle result);
-    void deliverCommandResult(IVoiceInteractorRequest request, in Bundle result);
+    void deliverCommandResult(IVoiceInteractorRequest request, boolean complete, in Bundle result);
     void deliverCancel(IVoiceInteractorRequest request);
 }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 326485d..69440be 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6279,6 +6279,7 @@
          its {@link android.service.voice.VoiceInteractionService#SERVICE_META_DATA} meta-data entry.
          Described here are the attributes that can be included in that tag. -->
     <declare-styleable name="VoiceInteractionService">
+        <attr name="sessionService" format="string" />
         <attr name="settingsActivity" />
     </declare-styleable>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 6491b33..f68f759 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2155,6 +2155,14 @@
   <public type="attr" name="colorPrimaryDark" />
   <public type="attr" name="colorAccent" />
   <public type="attr" name="nestedScrollingEnabled" />
+  <public type="attr" name="windowEnterTransition" />
+  <public type="attr" name="windowExitTransition" />
+  <public type="attr" name="windowSharedElementEnterTransition" />
+  <public type="attr" name="windowSharedElementExitTransition" />
+  <public type="attr" name="windowAllowExitTransitionOverlap" />
+  <public type="attr" name="windowAllowEnterTransitionOverlap" />
+  <public type="attr" name="sessionService" />
+  <public type="attr" name="switchStyle" />
 
   <public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
 
@@ -2385,17 +2393,14 @@
 
   <public type="style" name="Widget.Holo.Light.Button.Borderless" />
 
+  <public-padding type="interpolator" name="l_resource_pad" end="0x010c0010" />
+
   <!-- An interpolator which accelerates fast but decelerates slowly. -->
   <public type="interpolator" name="fast_out_slow_in" />
   <!-- An interpolator which starts with a peak non-zero velocity and decelerates slowly. -->
   <public type="interpolator" name="linear_out_slow_in" />
   <!-- An interpolator which accelerates fast and keeps accelerating until the end. -->
   <public type="interpolator" name="fast_out_linear_in" />
-  <public type="attr" name="windowEnterTransition" />
-  <public type="attr" name="windowExitTransition" />
-  <public type="attr" name="windowSharedElementEnterTransition" />
-  <public type="attr" name="windowSharedElementExitTransition" />
-  <public type="attr" name="windowAllowExitTransitionOverlap" />
-  <public type="attr" name="windowAllowEnterTransitionOverlap" />
+
   <public type="transition" name="no_transition" id="0x010f0000"/>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 431dab8..6e33bed 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -233,7 +233,6 @@
   <java-symbol type="attr" name="searchDialogTheme" />
   <java-symbol type="attr" name="searchViewSearchIcon" />
   <java-symbol type="attr" name="stackViewStyle" />
-  <java-symbol type="attr" name="switchStyle" />
   <java-symbol type="attr" name="textAppearanceAutoCorrectionSuggestion" />
   <java-symbol type="attr" name="textAppearanceEasyCorrectSuggestion" />
   <java-symbol type="attr" name="textAppearanceMisspelledSuggestion" />
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index e77564f..07a6a10 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
 
 import com.android.frameworks.coretests.R;
 import com.android.internal.content.PackageHelper;
@@ -48,6 +48,9 @@
 import android.os.storage.StorageResultCode;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -62,10 +65,6 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.StructStat;
-
 public class PackageManagerTests extends AndroidTestCase {
     private static final boolean localLOGV = true;
 
@@ -503,7 +502,7 @@
         final StructStat stat;
 
         try {
-            stat = Libcore.os.lstat(path);
+            stat = Os.lstat(path);
         } catch (ErrnoException e) {
             throw new AssertionError(reason + "\n" + "Got: " + path + " does not exist");
         }
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/core/tests/coretests/src/android/net/LinkAddressTest.java
index 17423be..bccf556 100644
--- a/core/tests/coretests/src/android/net/LinkAddressTest.java
+++ b/core/tests/coretests/src/android/net/LinkAddressTest.java
@@ -32,13 +32,13 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import static libcore.io.OsConstants.IFA_F_DEPRECATED;
-import static libcore.io.OsConstants.IFA_F_PERMANENT;
-import static libcore.io.OsConstants.IFA_F_TENTATIVE;
-import static libcore.io.OsConstants.RT_SCOPE_HOST;
-import static libcore.io.OsConstants.RT_SCOPE_LINK;
-import static libcore.io.OsConstants.RT_SCOPE_SITE;
-import static libcore.io.OsConstants.RT_SCOPE_UNIVERSE;
+import static android.system.OsConstants.IFA_F_DEPRECATED;
+import static android.system.OsConstants.IFA_F_PERMANENT;
+import static android.system.OsConstants.IFA_F_TENTATIVE;
+import static android.system.OsConstants.RT_SCOPE_HOST;
+import static android.system.OsConstants.RT_SCOPE_LINK;
+import static android.system.OsConstants.RT_SCOPE_SITE;
+import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
 /**
  * Tests for {@link LinkAddress}.
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index a602e07..553afe0 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -18,14 +18,13 @@
 
 import android.net.LinkProperties;
 import android.net.RouteInfo;
+import android.system.OsConstants;
 import android.test.suitebuilder.annotation.SmallTest;
 import junit.framework.TestCase;
 
 import java.net.InetAddress;
 import java.util.ArrayList;
 
-import libcore.io.OsConstants;
-
 public class LinkPropertiesTest extends TestCase {
     private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
     private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
index 824e108..0e8831f 100644
--- a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -501,10 +501,32 @@
     }
 
     private int drawRippleLayer(Canvas canvas, Rect bounds, boolean maskOnly) {
-        final Ripple[] activeRipples = mActiveRipples;
         final int ripplesCount = mActiveRipplesCount;
+        if (ripplesCount == 0) {
+            return -1;
+        }
 
-        Paint ripplePaint = null;
+        final Ripple[] activeRipples = mActiveRipples;
+        final boolean projected = isProjected();
+        final Rect layerBounds = projected ? getDirtyBounds() : bounds;
+
+        // Separate the ripple color and alpha channel. The alpha will be
+        // applied when we merge the ripples down to the canvas.
+        final int rippleColor;
+        if (mState.mTint != null) {
+            rippleColor = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
+        } else {
+            rippleColor = Color.TRANSPARENT;
+        }
+        final int rippleAlpha = Color.alpha(rippleColor);
+
+        if (mRipplePaint == null) {
+            mRipplePaint = new Paint();
+            mRipplePaint.setAntiAlias(true);
+        }
+        final Paint ripplePaint = mRipplePaint;
+        ripplePaint.setColor(rippleColor);
+
         boolean drewRipples = false;
         int restoreToCount = -1;
         int activeRipplesCount = 0;
@@ -524,20 +546,9 @@
             // If we're masking the ripple layer, make sure we have a layer
             // first. This will merge SRC_OVER (directly) onto the canvas.
             if (restoreToCount < 0) {
-                // Separate the ripple color and alpha channel. The alpha will be
-                // applied when we merge the ripples down to the canvas.
-                final int rippleColor;
-                if (mState.mTint != null) {
-                    rippleColor = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
-                } else {
-                    rippleColor = Color.TRANSPARENT;
-                }
-                final int rippleAlpha = Color.alpha(rippleColor);
-
                 // If we're projecting or we only have a mask, we want to treat the
                 // underlying canvas as our content and merge the ripple layer down
                 // using the tint xfermode.
-                final boolean projected = isProjected();
                 final PorterDuffXfermode xfermode;
                 if (projected || maskOnly) {
                     xfermode = mState.getTintXfermode();
@@ -547,18 +558,12 @@
 
                 final Paint layerPaint = getMaskingPaint(xfermode);
                 layerPaint.setAlpha(rippleAlpha);
-                final Rect layerBounds = projected ? getDirtyBounds() : bounds;
                 restoreToCount = canvas.saveLayer(layerBounds.left, layerBounds.top,
                         layerBounds.right, layerBounds.bottom, layerPaint);
                 layerPaint.setAlpha(255);
             }
 
-            if (mRipplePaint == null) {
-                mRipplePaint = new Paint();
-                mRipplePaint.setAntiAlias(true);
-            }
-
-            drewRipples |= ripple.draw(canvas, mRipplePaint);
+            drewRipples |= ripple.draw(canvas, ripplePaint);
 
             activeRipples[activeRipplesCount] = activeRipples[i];
             activeRipplesCount++;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 6424a98..9516bf8 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -44,6 +44,8 @@
 import android.sax.Element;
 import android.sax.ElementListener;
 import android.sax.RootElement;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Xml;
@@ -60,9 +62,6 @@
 import java.util.Iterator;
 import java.util.Locale;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-
 /**
  * Internal service helper that no-one should use directly.
  *
@@ -1130,7 +1129,7 @@
                         if (path != null && path.startsWith("/")) {
                             boolean exists = false;
                             try {
-                                exists = Libcore.os.access(path, libcore.io.OsConstants.F_OK);
+                                exists = Os.access(path, android.system.OsConstants.F_OK);
                             } catch (ErrnoException e1) {
                             }
                             if (!exists && !MtpConstants.isAbstractObject(format)) {
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 48ef9db..36c1d5c 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -41,6 +41,9 @@
 import android.os.ServiceManager;
 import android.os.StatFs;
 import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStatVfs;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 
@@ -66,11 +69,8 @@
 import javax.crypto.Mac;
 import javax.crypto.NoSuchPaddingException;
 
-import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 import libcore.io.Streams;
-import libcore.io.StructStatVfs;
 
 /*
  * This service copies a downloaded apk to a file passed in as
@@ -245,7 +245,7 @@
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
             try {
-                final StructStatVfs stat = Libcore.os.statvfs(path);
+                final StructStatVfs stat = Os.statvfs(path);
                 final long totalSize = stat.f_blocks * stat.f_bsize;
                 final long availSize = stat.f_bavail * stat.f_bsize;
                 return new long[] { totalSize, availSize };
@@ -379,7 +379,7 @@
         }
 
         try {
-            Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
+            Os.chmod(resFile.getAbsolutePath(), 0640);
         } catch (ErrnoException e) {
             Slog.e(TAG, "Could not chown APK: " + e.getMessage());
             PackageHelper.destroySdDir(newCid);
@@ -401,7 +401,7 @@
             }
 
             try {
-                Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644);
+                Os.chmod(publicZipFile.getAbsolutePath(), 0644);
             } catch (ErrnoException e) {
                 Slog.e(TAG, "Could not chown public resource file: " + e.getMessage());
                 PackageHelper.destroySdDir(newCid);
diff --git a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
index 5d2f330..d81e525 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml
@@ -19,34 +19,27 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:focusable="true"
+    android:clickable="true"
+    android:background="@*android:drawable/notification_quantum_bg_dim"
     >
-    <com.android.systemui.statusbar.LatestItemView
-        android:id="@+id/container"
+    <TextView
+        android:id="@+id/more_text"
         android:layout_width="match_parent"
-        android:layout_height="40dp"
-        android:layout_marginTop="@dimen/notification_divider_height"
-        android:focusable="true"
-        android:clickable="true"
-        android:background="@*android:drawable/notification_quantum_bg_dim"
-        >
-        <TextView
-            android:id="@+id/more_text"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:gravity="center_horizontal"
-            android:textColor="@color/keyguard_overflow_content_color"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            />
-        <com.android.systemui.statusbar.NotificationOverflowIconsView
-            android:id="@+id/overflow_icons_view"
-            android:layout_gravity="end|center_vertical"
-            android:gravity="end"
-            android:paddingLeft="8dp"
-            android:paddingRight="8dp"
-            android:layout_width="120dp"
-            android:layout_height="wrap_content"
-            />
-    </com.android.systemui.statusbar.LatestItemView>
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:gravity="center_horizontal"
+        android:textColor="@color/keyguard_overflow_content_color"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        />
+    <com.android.systemui.statusbar.NotificationOverflowIconsView
+        android:id="@+id/overflow_icons_view"
+        android:layout_gravity="end|center_vertical"
+        android:gravity="end"
+        android:paddingLeft="8dp"
+        android:paddingRight="8dp"
+        android:layout_width="120dp"
+        android:layout_height="wrap_content"
+        />
 </com.android.systemui.statusbar.NotificationOverflowContainer>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index d61d8b9..41e7dac 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -2,17 +2,18 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:focusable="true"
+    android:clickable="true"
+    android:background="@*android:drawable/notification_quantum_bg"
     >
 
-    <View
-        android:id="@+id/top_glow"
-        android:alpha="0"
-        android:visibility="invisible"
+    <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded"
+       android:layout_width="match_parent"
+       android:layout_height="wrap_content" />
+
+    <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expandedPublic"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/notification_divider_height"
-        android:layout_gravity="top|center_horizontal"
-        android:background="@drawable/top_divider_glow"
-        />
+        android:layout_height="wrap_content" />
 
     <Button
         android:id="@+id/veto"
@@ -25,35 +26,6 @@
         android:paddingStart="8dp"
         />
 
-    <com.android.systemui.statusbar.LatestItemView android:id="@+id/container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/notification_divider_height"
-        android:layout_marginTop="@dimen/notification_divider_height"
-        android:focusable="true"
-        android:clickable="true"
-        android:background="@*android:drawable/notification_quantum_bg"
-        >
-
-        <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded"
-           android:layout_width="match_parent"
-           android:layout_height="wrap_content" />
-
-        <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expandedPublic"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-    </com.android.systemui.statusbar.LatestItemView>
-
-    <View
-        android:id="@+id/bottom_glow"
-        android:alpha="0"
-        android:visibility="invisible"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/notification_divider_height"
-        android:layout_gravity="bottom|center_horizontal"
-        android:background="@drawable/bottom_divider_glow"
-        />
-
     <TextView
         android:id="@+id/debug_info"
         android:visibility="invisible"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 0604817..176879e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -82,12 +82,6 @@
     <!-- Height of a medium notification in the status bar -->
     <dimen name="notification_mid_height">128dp</dimen>
 
-    <!-- Height of a small notification in the status bar plus glow, padding, etc -->
-    <dimen name="notification_row_min_height">68dp</dimen>
-
-    <!-- Height of a large notification in the status bar plus glow, padding, etc -->
-    <dimen name="notification_row_max_height">260dp</dimen>
-
     <!-- size at which Notification icons will be drawn in the status bar -->
     <dimen name="status_bar_icon_drawing_size">18dip</dimen>
 
@@ -261,6 +255,9 @@
     <!-- Z distance between notifications if they are in the stack -->
     <dimen name="z_distance_between_notifications">2dp</dimen>
 
+    <!-- The padding between the individual notification cards. -->
+    <dimen name="notification_padding">3dp</dimen>
+
     <!-- Width of the zen mode interstitial dialog. -->
     <dimen name="zen_mode_dialog_width">320dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 8dd3f8d..c585a5b 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -19,7 +19,6 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.media.AudioManager;
@@ -81,8 +80,6 @@
     private boolean mHasPopped;
     private View mEventSource;
     private View mCurrView;
-    private View mCurrViewTopGlow;
-    private View mCurrViewBottomGlow;
     private float mOldHeight;
     private float mNaturalHeight;
     private float mInitialTouchFocusY;
@@ -99,9 +96,6 @@
     private ScaleGestureDetector mSGD;
     private ViewScaler mScaler;
     private ObjectAnimator mScaleAnimation;
-    private AnimatorSet mGlowAnimationSet;
-    private ObjectAnimator mGlowTopAnimation;
-    private ObjectAnimator mGlowBottomAnimation;
     private Vibrator mVibrator;
 
     private int mSmallSize;
@@ -223,14 +217,6 @@
             }
         };
 
-        mGlowTopAnimation = ObjectAnimator.ofFloat(null, "alpha", 0f);
-        mGlowTopAnimation.addListener(glowVisibilityController);
-        mGlowBottomAnimation = ObjectAnimator.ofFloat(null, "alpha", 0f);
-        mGlowBottomAnimation.addListener(glowVisibilityController);
-        mGlowAnimationSet = new AnimatorSet();
-        mGlowAnimationSet.play(mGlowTopAnimation).with(mGlowBottomAnimation);
-        mGlowAnimationSet.setDuration(GLOW_DURATION);
-
         final ViewConfiguration configuration = ViewConfiguration.get(mContext);
         mTouchSlop = configuration.getScaledTouchSlop();
 
@@ -251,7 +237,6 @@
         float newHeight = clamp(target);
         mScaler.setHeight(newHeight);
 
-        setGlow(calculateGlow(target, newHeight));
         mLastFocusY = mSGD.getFocusY();
         mLastSpanY = mSGD.getCurrentSpan();
     }
@@ -322,37 +307,6 @@
         return (GLOW_BASE + strength * (1f - GLOW_BASE));
     }
 
-    public void setGlow(float glow) {
-        if (!mGlowAnimationSet.isRunning() || glow == 0f) {
-            if (mGlowAnimationSet.isRunning()) {
-                mGlowAnimationSet.end();
-            }
-            if (mCurrViewTopGlow != null && mCurrViewBottomGlow != null) {
-                if (glow == 0f || mCurrViewTopGlow.getAlpha() == 0f) {
-                    // animate glow in and out
-                    mGlowTopAnimation.setTarget(mCurrViewTopGlow);
-                    mGlowBottomAnimation.setTarget(mCurrViewBottomGlow);
-                    mGlowTopAnimation.setFloatValues(glow);
-                    mGlowBottomAnimation.setFloatValues(glow);
-                    mGlowAnimationSet.setupStartValues();
-                    mGlowAnimationSet.start();
-                } else {
-                    // set it explicitly in reponse to touches.
-                    mCurrViewTopGlow.setAlpha(glow);
-                    mCurrViewBottomGlow.setAlpha(glow);
-                    handleGlowVisibility();
-                }
-            }
-        }
-    }
-
-    private void handleGlowVisibility() {
-        mCurrViewTopGlow.setVisibility(mCurrViewTopGlow.getAlpha() <= 0.0f ?
-                View.INVISIBLE : View.VISIBLE);
-        mCurrViewBottomGlow.setVisibility(mCurrViewBottomGlow.getAlpha() <= 0.0f ?
-                View.INVISIBLE : View.VISIBLE);
-    }
-
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         final int action = ev.getAction();
@@ -466,9 +420,6 @@
 
                     if (mHasPopped) {
                         mScaler.setHeight(newHeight);
-                        setGlow(GLOW_BASE);
-                    } else {
-                        setGlow(calculateGlow(4f * pull, 0f));
                     }
 
                     final int x = (int) mSGD.getFocusX();
@@ -517,7 +468,6 @@
         if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v);
         mCallback.setUserLockedChild(v, true);
         setView(v);
-        setGlow(GLOW_BASE);
         mScaler.setView(v);
         mOldHeight = mScaler.getHeight();
         if (mCallback.canChildBeExpanded(v)) {
@@ -549,7 +499,6 @@
         if (mScaleAnimation.isRunning()) {
             mScaleAnimation.cancel();
         }
-        setGlow(0f);
         mCallback.setUserExpandedChild(mCurrView, h == mNaturalHeight);
         if (targetHeight != currentHeight) {
             mScaleAnimation.setFloatValues(targetHeight);
@@ -571,23 +520,11 @@
 
     private void clearView() {
         mCurrView = null;
-        mCurrViewTopGlow = null;
-        mCurrViewBottomGlow = null;
+
     }
 
     private void setView(View v) {
         mCurrView = v;
-        if (v instanceof ViewGroup) {
-            ViewGroup g = (ViewGroup) v;
-            mCurrViewTopGlow = g.findViewById(R.id.top_glow);
-            mCurrViewBottomGlow = g.findViewById(R.id.bottom_glow);
-            if (DEBUG) {
-                String debugLog = "Looking for glows: " +
-                        (mCurrViewTopGlow != null ? "found top " : "didn't find top") +
-                        (mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
-                Log.v(TAG,  debugLog);
-            }
-        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 5e90084..d647dfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2014 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.
@@ -11,7 +11,7 @@
  * 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.
+ * limitations under the License
  */
 
 package com.android.systemui.statusbar;
@@ -21,12 +21,15 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 
 import com.android.internal.R;
 
-public class LatestItemView extends FrameLayout {
+/**
+ * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
+ * to implement dimming/activating on Keyguard for the double-tap gesture
+ */
+public class ActivatableNotificationView extends FrameLayout {
 
     private static final long DOUBLETAP_TIMEOUT_MS = 1000;
 
@@ -48,11 +51,12 @@
 
     private OnActivatedListener mOnActivatedListener;
 
-    public LatestItemView(Context context, AttributeSet attrs) {
+    public ActivatableNotificationView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
     }
 
+
     private final Runnable mTapTimeoutRunnable = new Runnable() {
         @Override
         public void run() {
@@ -66,20 +70,6 @@
     }
 
     @Override
-    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
-        if (super.onRequestSendAccessibilityEvent(child, event)) {
-            // Add a record for the entire layout since its content is somehow small.
-            // The event comes from a leaf view that is interacted with.
-            AccessibilityEvent record = AccessibilityEvent.obtain();
-            onInitializeAccessibilityEvent(record);
-            dispatchPopulateAccessibilityEvent(record);
-            event.appendRecord(record);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
     public boolean onTouchEvent(MotionEvent event) {
         if (mLocked) {
             return handleTouchEventLocked(event);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 8f3c078..3e21640 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -83,7 +83,7 @@
 import java.util.Locale;
 
 public abstract class BaseStatusBar extends SystemUI implements
-        CommandQueue.Callbacks, LatestItemView.OnActivatedListener {
+        CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener {
     public static final String TAG = "StatusBar";
     public static final boolean DEBUG = false;
     public static final boolean MULTIUSER_DEBUG = false;
@@ -760,20 +760,19 @@
         // NB: the large icon is now handled entirely by the template
 
         // bind the click event to the content area
-        ViewGroup content = (ViewGroup)row.findViewById(R.id.container);
         SizeAdaptiveLayout expanded = (SizeAdaptiveLayout)row.findViewById(R.id.expanded);
         SizeAdaptiveLayout expandedPublic
                 = (SizeAdaptiveLayout)row.findViewById(R.id.expandedPublic);
 
-        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+        row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
 
         PendingIntent contentIntent = sbn.getNotification().contentIntent;
         if (contentIntent != null) {
             final View.OnClickListener listener = makeClicker(contentIntent,
                     sbn.getPackageName(), sbn.getTag(), sbn.getId(), isHeadsUp, sbn.getUserId());
-            content.setOnClickListener(listener);
+            row.setOnClickListener(listener);
         } else {
-            content.setOnClickListener(null);
+            row.setOnClickListener(null);
         }
 
         // set up the adaptive layout
@@ -883,7 +882,6 @@
         entry.row = row;
         entry.row.setHeightRange(mRowMinHeight, mRowMaxHeight);
         entry.row.setOnActivatedListener(this);
-        entry.content = content;
         entry.expanded = contentViewLocal;
         entry.expandedPublic = publicViewLocal;
         entry.setBigContentView(bigContentViewLocal);
@@ -1350,9 +1348,9 @@
             final View.OnClickListener listener = makeClicker(contentIntent,
                     notification.getPackageName(), notification.getTag(), notification.getId(),
                     isHeadsUp, notification.getUserId());
-            entry.content.setOnClickListener(listener);
+            entry.row.setOnClickListener(listener);
         } else {
-            entry.content.setOnClickListener(null);
+            entry.row.setOnClickListener(null);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index bb481ec..35c02eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -20,13 +20,12 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.FrameLayout;
+import android.view.accessibility.AccessibilityEvent;
 
 import com.android.internal.widget.SizeAdaptiveLayout;
 import com.android.systemui.R;
 
-public class ExpandableNotificationRow extends FrameLayout
-        implements LatestItemView.OnActivatedListener {
+public class ExpandableNotificationRow extends ActivatableNotificationView {
     private int mRowMinHeight;
     private int mRowMaxHeight;
 
@@ -41,8 +40,6 @@
     /** Are we showing the "public" version */
     private boolean mShowingPublic;
 
-    private LatestItemView mLatestItemView;
-
     /**
      * Is this notification expanded by the system. The expansion state can be overridden by the
      * user expansion.
@@ -53,7 +50,6 @@
     private int mMaxExpandHeight;
     private boolean mMaxHeightNeedsUpdate;
     private NotificationActivator mActivator;
-    private LatestItemView.OnActivatedListener mOnActivatedListener;
     private boolean mSelfInitiatedLayout;
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
@@ -65,10 +61,22 @@
         super.onFinishInflate();
         mPublicLayout = (SizeAdaptiveLayout) findViewById(R.id.expandedPublic);
         mPrivateLayout = (SizeAdaptiveLayout) findViewById(R.id.expanded);
-        mLatestItemView = (LatestItemView) findViewById(R.id.container);
 
         mActivator = new NotificationActivator(this);
-        mLatestItemView.setOnActivatedListener(this);
+    }
+
+    @Override
+    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+        if (super.onRequestSendAccessibilityEvent(child, event)) {
+            // Add a record for the entire layout since its content is somehow small.
+            // The event comes from a leaf view that is interacted with.
+            AccessibilityEvent record = AccessibilityEvent.obtain();
+            onInitializeAccessibilityEvent(record);
+            dispatchPopulateAccessibilityEvent(record);
+            event.appendRecord(record);
+            return true;
+        }
+        return false;
     }
 
     public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
@@ -220,7 +228,7 @@
      * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
      */
     public void setDimmed(boolean dimmed) {
-        mLatestItemView.setDimmed(dimmed);
+        super.setDimmed(dimmed);
         mActivator.setDimmed(dimmed);
     }
 
@@ -232,46 +240,10 @@
         return mMaxExpandHeight;
     }
 
-    /**
-     * Sets the notification as locked. In the locked state, the first tap will produce a quantum
-     * ripple to make the notification brighter and only the second tap will cause a click.
-     */
-    public void setLocked(boolean locked) {
-        mLatestItemView.setLocked(locked);
-    }
-
-    public void setOnActivatedListener(LatestItemView.OnActivatedListener listener) {
-        mOnActivatedListener = listener;
-    }
-
     public NotificationActivator getActivator() {
         return mActivator;
     }
 
-    @Override
-    public void onActivated(View view) {
-        if (mOnActivatedListener != null) {
-            mOnActivatedListener.onActivated(this);
-        }
-    }
-
-    @Override
-    public void onReset(View view) {
-        if (mOnActivatedListener != null) {
-            mOnActivatedListener.onReset(this);
-        }
-    }
-
-    /**
-     * Sets the resource id for the background of this notification.
-     *
-     * @param bgResId The background resource to use in normal state.
-     * @param dimmedBgResId The background resource to use in dimmed state.
-     */
-    public void setBackgroundResourceIds(int bgResId, int dimmedBgResId) {
-        mLatestItemView.setBackgroundResourceIds(bgResId, dimmedBgResId);
-    }
-
     /**
      * @return the potential height this view could expand in addition.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index d563968..6401695 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -107,7 +107,7 @@
            mBar.updateNotification(mSynKey, sbn);
         }
         final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey);
-        entry.content.setOnClickListener(mSynClickListener);
+        entry.row.setOnClickListener(mSynClickListener);
     }
 
     private final View.OnClickListener mSynClickListener = new View.OnClickListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index b9a59dd..6b6f55a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -33,7 +33,6 @@
         public StatusBarNotification notification;
         public StatusBarIconView icon;
         public ExpandableNotificationRow row; // the outer expanded view
-        public View content; // takes the click events and sends the PendingIntent
         public View expanded; // the inflated RemoteViews
         public View expandedPublic; // for insecure lockscreens
         public ImageView largeIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
index be58dad..af91314 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import com.android.systemui.R;
@@ -27,65 +25,30 @@
 /**
  * Container view for overflowing notification icons on Keyguard.
  */
-public class NotificationOverflowContainer extends FrameLayout
-        implements LatestItemView.OnActivatedListener {
+public class NotificationOverflowContainer extends ActivatableNotificationView {
 
     private NotificationOverflowIconsView mIconsView;
-    private LatestItemView.OnActivatedListener mOnActivatedListener;
     private NotificationActivator mActivator;
 
-    public NotificationOverflowContainer(Context context) {
-        super(context);
-    }
-
     public NotificationOverflowContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    public NotificationOverflowContainer(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public NotificationOverflowContainer(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view);
         mIconsView.setMoreText((TextView) findViewById(R.id.more_text));
 
-        LatestItemView latestItemView = (LatestItemView) findViewById(R.id.container);
         mActivator = new NotificationActivator(this);
         mActivator.setDimmed(true);
-        latestItemView.setOnActivatedListener(this);
-        latestItemView.setLocked(true);
+        setLocked(true);
     }
 
     public NotificationOverflowIconsView getIconsView() {
         return mIconsView;
     }
 
-    public void setOnActivatedListener(LatestItemView.OnActivatedListener onActivatedListener) {
-        mOnActivatedListener = onActivatedListener;
-    }
-
-    @Override
-    public void onActivated(View view) {
-        if (mOnActivatedListener != null) {
-            mOnActivatedListener.onActivated(this);
-        }
-    }
-
-    @Override
-    public void onReset(View view) {
-        if (mOnActivatedListener != null) {
-            mOnActivatedListener.onReset(this);
-        }
-    }
-
     public NotificationActivator getActivator() {
         return mActivator;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 0e5e2f4..545352c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1625,9 +1625,9 @@
         return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
     }
 
-    void makeExpandedVisible() {
+    void makeExpandedVisible(boolean force) {
         if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
-        if (mExpandedVisible || !panelsEnabled()) {
+        if (!force && (mExpandedVisible || !panelsEnabled())) {
             return;
         }
 
@@ -2718,8 +2718,8 @@
         }
 
         mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
-        mRowMinHeight =  res.getDimensionPixelSize(R.dimen.notification_row_min_height);
-        mRowMaxHeight =  res.getDimensionPixelSize(R.dimen.notification_row_max_height);
+        mRowMinHeight =  res.getDimensionPixelSize(R.dimen.notification_min_height);
+        mRowMaxHeight =  res.getDimensionPixelSize(R.dimen.notification_max_height);
 
         mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
 
@@ -3009,8 +3009,9 @@
 
     private void instantExpandNotificationsPanel() {
 
-        // Make our window larger.
-        mStatusBarWindowManager.setStatusBarExpanded(true);
+        // Make our window larger and the panel visible.
+        makeExpandedVisible(true);
+        mNotificationPanel.setVisibility(View.VISIBLE);
 
         // Wait for window manager to pickup the change, so we know the maximum height of the panel
         // then.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index bf7dd5c..79c63f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -106,7 +106,7 @@
     @Override
     public void onPanelPeeked() {
         super.onPanelPeeked();
-        mBar.makeExpandedVisible();
+        mBar.makeExpandedVisible(false);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index c5dae85..6b5ef5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -69,8 +69,8 @@
         mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
                 R.id.notification_stack_scroller);
         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
-        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
-        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
+        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
         mExpandHelper = new ExpandHelper(getContext(), mStackScrollLayout,
                 minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
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 2dba669..c94c65f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -135,8 +135,8 @@
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
         mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop);
 
-        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
-        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
+        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
         mExpandHelper = new ExpandHelper(getContext(), this, minHeight, maxHeight);
 
         mContentHolder = (ViewGroup) findViewById(R.id.content_holder);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 36d94a9..948ef90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -145,13 +145,13 @@
         mSidePaddings = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_side_padding);
         mCollapsedSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_row_min_height);
+                .getDimensionPixelSize(R.dimen.notification_min_height);
         mBottomStackPeekSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
         mEmptyMarginBottom = context.getResources().getDimensionPixelSize(
                 R.dimen.notification_stack_margin_bottom);
-        // currently the padding is in the elements themself
-        mPaddingBetweenElements = 0;
+        mPaddingBetweenElements = context.getResources()
+                .getDimensionPixelSize(R.dimen.notification_padding);
         mStackScrollAlgorithm = new StackScrollAlgorithm(context);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index d9e7f66..2a6e4ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -62,11 +62,10 @@
     }
 
     private void initConstants(Context context) {
-
-        // currently the padding is in the elements themself
-        mPaddingBetweenElements = 0;
+        mPaddingBetweenElements = context.getResources()
+                .getDimensionPixelSize(R.dimen.notification_padding);
         mCollapsedSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_row_min_height);
+                .getDimensionPixelSize(R.dimen.notification_min_height);
         mTopStackPeekSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.top_stack_peek_amount);
         mBottomStackPeekSize = context.getResources()
@@ -323,7 +322,8 @@
         // the offset starting at the transitionPosition of the bottom stack
         float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom);
         algorithmState.itemsInBottomStack += algorithmState.partialInBottom;
-        childViewState.yTranslation = transitioningPositionStart + offset - childHeight;
+        childViewState.yTranslation = transitioningPositionStart + offset - childHeight
+                - mPaddingBetweenElements;
 
         // We want at least to be at the end of the top stack when collapsing
         clampPositionToTopStackEnd(childViewState, childHeight);
@@ -339,7 +339,8 @@
         if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) {
             // We are visually entering the bottom stack
             currentYPosition = transitioningPositionStart
-                    + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack);
+                    + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack)
+                    - mPaddingBetweenElements;
             childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_PEEKING;
         } else {
             // we are fully inside the stack
@@ -542,9 +543,13 @@
                                 public void onLayoutChange(View v, int left, int top, int right,
                                         int bottom, int oldLeft, int oldTop, int oldRight,
                                         int oldBottom) {
-                                    mFirstChildMaxHeight = getMaxAllowedChildHeight(
-                                            mFirstChildWhileExpanding);
-                                    mFirstChildWhileExpanding.removeOnLayoutChangeListener(this);
+                                    if (mFirstChildWhileExpanding != null) {
+                                        mFirstChildMaxHeight = getMaxAllowedChildHeight(
+                                                mFirstChildWhileExpanding);
+                                    } else {
+                                        mFirstChildMaxHeight = 0;
+                                    }
+                                    v.removeOnLayoutChangeListener(this);
                                 }
                             });
                 } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 9742e65..6e2e87e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -197,18 +197,12 @@
      * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
      */
     private void updateChildClip(View child, int height, float clipHeight) {
-        // The children currently have paddings inside themselfs because of the expansion
-        // visualization. In order for the clipping to work correctly we have to set the correct
-        // clip rect on the child.
-        View container = child.findViewById(R.id.container);
-        if (container != null) {
-            int clipInset = (int) (height - clipHeight);
-            mClipRect.set(0,
-                    clipInset,
-                    child.getWidth(),
-                    height);
-            child.setClipBounds(mClipRect);
-        }
+        int clipInset = (int) (height - clipHeight);
+        mClipRect.set(0,
+                clipInset,
+                child.getWidth(),
+                height);
+        child.setClipBounds(mClipRect);
     }
 
     /**
@@ -218,22 +212,15 @@
      * @param height the currently applied height of the view
      * @param outlineHeight the desired height of the outline, the outline ends on the bottom
      */
-    private void updateChildOutline(View child,
-            int height,
-            float outlineHeight) {
-        // The children currently have paddings inside themselfs because of the expansion
-        // visualization. In order for the shadows to work correctly we have to set the correct
-        // outline on the child.
-        View container = child.findViewById(R.id.container);
-        if (container != null) {
-            int shadowInset = (int) (height - outlineHeight);
-            getOutlineForSize(container.getLeft(),
-                    container.getTop() + shadowInset,
-                    container.getWidth(),
-                    container.getHeight() - shadowInset,
-                    mChildOutline);
-            child.setOutline(mChildOutline);
-        }
+    private void updateChildOutline(View child, int height,
+        float outlineHeight) {
+        int shadowInset = (int) (height - outlineHeight);
+        getOutlineForSize(child.getLeft(),
+                child.getTop() + shadowInset,
+                child.getWidth(),
+                child.getHeight() - shadowInset,
+                mChildOutline);
+        child.setOutline(mChildOutline);
     }
 
     private void getOutlineForSize(int leftInset, int topInset, int width, int height,
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index fa803e2..fe97c71 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -421,11 +421,8 @@
                 }
 
                 /* This goes in response as msg.arg2 */
-                int clientId = -1;
-                int keyId = clientInfo.mClientIds.indexOfValue(id);
-                if (keyId != -1) {
-                    clientId = clientInfo.mClientIds.keyAt(keyId);
-                } else {
+                int clientId = clientInfo.getClientId(id);
+                if (clientId < 0) {
                     // This can happen because of race conditions. For example,
                     // SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY,
                     // and we may get in this situation.
@@ -904,5 +901,18 @@
             mClientRequests.clear();
         }
 
+        // mClientIds is a sparse array of listener id -> mDnsClient id.  For a given mDnsClient id,
+        // return the corresponding listener id.  mDnsClient id is also called a global id.
+        private int getClientId(final int globalId) {
+            // This doesn't use mClientIds.indexOfValue because indexOfValue uses == (not .equals)
+            // while also coercing the int primitives to Integer objects.
+            for (int i = 0, nSize = mClientIds.size(); i < nSize; i++) {
+                int mDnsId = mClientIds.valueAt(i);
+                if (globalId == mDnsId) {
+                    return mClientIds.keyAt(i);
+                }
+            }
+            return -1;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2c623b5..3111cce 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -23,13 +23,13 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.system.OsConstants.S_IRWXU;
+import static android.system.OsConstants.S_IRGRP;
+import static android.system.OsConstants.S_IXGRP;
+import static android.system.OsConstants.S_IROTH;
+import static android.system.OsConstants.S_IXOTH;
 import static com.android.internal.util.ArrayUtils.appendInt;
 import static com.android.internal.util.ArrayUtils.removeInt;
-import static libcore.io.OsConstants.S_IRWXU;
-import static libcore.io.OsConstants.S_IRGRP;
-import static libcore.io.OsConstants.S_IXGRP;
-import static libcore.io.OsConstants.S_IROTH;
-import static libcore.io.OsConstants.S_IXOTH;
 
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.app.ResolverActivity;
@@ -119,6 +119,9 @@
 import android.os.UserManager;
 import android.security.KeyStore;
 import android.security.SystemKeyStore;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -157,10 +160,7 @@
 import java.util.Map;
 import java.util.Set;
 
-import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
-import libcore.io.StructStat;
 
 import com.android.internal.R;
 import com.android.server.storage.DeviceStorageMonitorInternal;
@@ -4727,7 +4727,7 @@
             if (dataPath.exists()) {
                 int currentUid = 0;
                 try {
-                    StructStat stat = Libcore.os.stat(dataPath.getPath());
+                    StructStat stat = Os.stat(dataPath.getPath());
                     currentUid = stat.st_uid;
                 } catch (ErrnoException e) {
                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
@@ -5498,8 +5498,7 @@
             }
 
             try {
-                Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
-                        | S_IXOTH);
+                Os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
             } catch (ErrnoException e) {
                 throw new IOException("Cannot chmod native library directory "
                         + nativeLibraryDir.getPath(), e);
diff --git a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
index fdc604f..3c960c7 100644
--- a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
@@ -20,6 +20,8 @@
 import android.content.Intent;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.util.Base64;
 import android.util.Slog;
 
@@ -28,9 +30,7 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 
-import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 public class SELinuxPolicyInstallReceiver extends ConfigUpdateInstallReceiver {
 
@@ -110,16 +110,16 @@
         File update = new File(updateDir.getParentFile(), "update");
         File tmp = new File(updateDir.getParentFile(), "tmp");
         if (current.exists()) {
-            Libcore.os.symlink(updateDir.getPath(), update.getPath());
-            Libcore.os.rename(update.getPath(), current.getPath());
+            Os.symlink(updateDir.getPath(), update.getPath());
+            Os.rename(update.getPath(), current.getPath());
         } else {
-            Libcore.os.symlink(updateDir.getPath(), current.getPath());
+            Os.symlink(updateDir.getPath(), current.getPath());
         }
         contexts.mkdirs();
         backupContexts(contexts);
         copyUpdate(contexts);
-        Libcore.os.symlink(contexts.getPath(), tmp.getPath());
-        Libcore.os.rename(tmp.getPath(), current.getPath());
+        Os.symlink(contexts.getPath(), tmp.getPath());
+        Os.rename(tmp.getPath(), current.getPath());
         SystemProperties.set("selinux.reload_policy", "1");
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 08b1eba..3d82027 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -60,6 +60,7 @@
 import com.android.server.am.BatteryStatsService;
 import com.android.server.clipboard.ClipboardService;
 import com.android.server.content.ContentService;
+import com.android.server.devicepolicy.DevicePolicyManagerService;
 import com.android.server.display.DisplayManagerService;
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.hdmi.HdmiControlService;
@@ -112,8 +113,6 @@
      */
     private static final String BACKUP_MANAGER_SERVICE_CLASS =
             "com.android.server.backup.BackupManagerService$Lifecycle";
-    private static final String DEVICE_POLICY_MANAGER_SERVICE_CLASS =
-            "com.android.server.devicepolicy.DevicePolicyManagerService$Lifecycle";
     private static final String APPWIDGET_SERVICE_CLASS =
             "com.android.server.appwidget.AppWidgetService";
     private static final String VOICE_RECOGNITION_MANAGER_SERVICE_CLASS =
@@ -555,9 +554,9 @@
                 }
 
                 try {
-                    if (pm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
-                        mSystemServiceManager.startService(DEVICE_POLICY_MANAGER_SERVICE_CLASS);
-                    }
+                    // Always start the Device Policy Manager, so that the API is compatible with
+                    // API8.
+                    mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
                 } catch (Throwable e) {
                     reportWtf("starting DevicePolicyService", e);
                 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 9e2bcab..045c0f6 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -16,14 +16,18 @@
 
 package com.android.server.voiceinteraction;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionService;
@@ -134,9 +138,8 @@
         }
 
         @Override
-        public int startVoiceActivity(Intent intent, String resolvedType,
-                IVoiceInteractionService service,
-                IVoiceInteractionSession session, IVoiceInteractor interactor) {
+        public void startVoiceActivity(Intent intent, String resolvedType,
+                IVoiceInteractionService service, Bundle args) {
             synchronized (this) {
                 if (mImpl == null || service.asBinder() != mImpl.mService.asBinder()) {
                     throw new SecurityException(
@@ -146,8 +149,8 @@
                 final int callingUid = Binder.getCallingUid();
                 final long caller = Binder.clearCallingIdentity();
                 try {
-                    return mImpl.startVoiceActivityLocked(callingPid, callingUid,
-                            intent, resolvedType, session, interactor);
+                    mImpl.startVoiceActivityLocked(callingPid, callingUid,
+                            intent, resolvedType, args);
                 } finally {
                     Binder.restoreCallingIdentity(caller);
                 }
@@ -155,8 +158,43 @@
         }
 
         @Override
+        public int deliverNewSession(IBinder token, IVoiceInteractionSession session,
+                IVoiceInteractor interactor) {
+            synchronized (this) {
+                if (mImpl == null) {
+                    Slog.w(TAG, "deliverNewSession without running voice interaction service");
+                    return ActivityManager.START_CANCELED;
+                }
+                final int callingPid = Binder.getCallingPid();
+                final int callingUid = Binder.getCallingUid();
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    return mImpl.deliverNewSessionLocked(callingPid, callingUid, token, session,
+                            interactor);
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+                pw.println("Permission Denial: can't dump PowerManager from from pid="
+                        + Binder.getCallingPid()
+                        + ", uid=" + Binder.getCallingUid());
+                return;
+            }
+            synchronized (this) {
+                pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+                if (mImpl == null) {
+                    pw.println("  (No active implementation)");
+                    return;
+                }
+                mImpl.dumpLocked(fd, pw, args);
+            }
         }
 
         class SettingsObserver extends ContentObserver {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index af8ae1e..6bbd1c1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.server.voiceinteraction;
 
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.content.ComponentName;
@@ -24,29 +25,40 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
+import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionService;
 import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.IVoiceInteractionSessionService;
 import android.service.voice.VoiceInteractionService;
+import android.service.voice.VoiceInteractionServiceInfo;
 import android.util.Slog;
 import com.android.internal.app.IVoiceInteractor;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 class VoiceInteractionManagerServiceImpl {
     final static String TAG = "VoiceInteractionServiceManager";
 
+    final boolean mValid;
+
     final Context mContext;
     final Handler mHandler;
     final Object mLock;
     final int mUser;
     final ComponentName mComponent;
     final IActivityManager mAm;
+    final VoiceInteractionServiceInfo mInfo;
+    final ComponentName mSessionComponentName;
     boolean mBound = false;
     IVoiceInteractionService mService;
-    IVoiceInteractionSession mActiveSession;
-    IVoiceInteractor mActiveInteractor;
+
+    SessionConnection mActiveSession;
 
     final ServiceConnection mConnection = new ServiceConnection() {
         @Override
@@ -62,6 +74,72 @@
         }
     };
 
+    final class SessionConnection implements ServiceConnection {
+        final IBinder mToken = new Binder();
+        final Intent mIntent;
+        final String mResolvedType;
+        final Bundle mArgs;
+        boolean mBound;
+        IVoiceInteractionSessionService mService;
+        IVoiceInteractionSession mSession;
+        IVoiceInteractor mInteractor;
+
+        SessionConnection(Intent intent, String resolvedType, Bundle args) {
+            mIntent = intent;
+            mResolvedType = resolvedType;
+            mArgs = args;
+            Intent serviceIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+            serviceIntent.setComponent(mSessionComponentName);
+            mBound = mContext.bindServiceAsUser(serviceIntent, this,
+                    Context.BIND_AUTO_CREATE, new UserHandle(mUser));
+            if (!mBound) {
+                Slog.w(TAG, "Failed binding to voice interaction session service " + mComponent);
+            }
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (mLock) {
+                mService = IVoiceInteractionSessionService.Stub.asInterface(service);
+                if (mActiveSession == this) {
+                    try {
+                        mService.newSession(mToken, mArgs);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed making new session", e);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mService = null;
+        }
+
+        public void cancel() {
+            if (mBound) {
+                mContext.unbindService(this);
+                mBound = false;
+                mService = null;
+                mSession = null;
+                mInteractor = null;
+            }
+        }
+
+        public void dump(String prefix, PrintWriter pw) {
+            pw.print(prefix); pw.print("mToken="); pw.println(mToken);
+            pw.print(prefix); pw.print("mIntent="); pw.println(mIntent);
+                    pw.print(" mResolvedType="); pw.println(mResolvedType);
+            pw.print(prefix); pw.print("mArgs="); pw.println(mArgs);
+            pw.print(prefix); pw.print("mBound="); pw.println(mBound);
+            if (mBound) {
+                pw.print(prefix); pw.print("mService="); pw.println(mService);
+                pw.print(prefix); pw.print("mSession="); pw.println(mSession);
+                pw.print(prefix); pw.print("mInteractor="); pw.println(mInteractor);
+            }
+        }
+    };
+
     VoiceInteractionManagerServiceImpl(Context context, Handler handler, Object lock,
             int userHandle, ComponentName service) {
         mContext = context;
@@ -70,50 +148,85 @@
         mUser = userHandle;
         mComponent = service;
         mAm = ActivityManagerNative.getDefault();
+        VoiceInteractionServiceInfo info;
+        try {
+            info = new VoiceInteractionServiceInfo(context.getPackageManager(), service);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.w(TAG, "Voice interaction service not found: " + service);
+            mInfo = null;
+            mSessionComponentName = null;
+            mValid = false;
+            return;
+        }
+        mInfo = info;
+        if (mInfo.getParseError() != null) {
+            Slog.w(TAG, "Bad voice interaction service: " + mInfo.getParseError());
+            mSessionComponentName = null;
+            mValid = false;
+            return;
+        }
+        mValid = true;
+        mSessionComponentName = new ComponentName(service.getPackageName(),
+                mInfo.getSessionService());
     }
 
-    public int startVoiceActivityLocked(int callingPid, int callingUid, Intent intent,
-            String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor) {
-        if (session == null) {
-            throw new NullPointerException("session is null");
-        }
-        if (interactor == null) {
-            throw new NullPointerException("interactor is null");
-        }
+    public void startVoiceActivityLocked(int callingPid, int callingUid, Intent intent,
+            String resolvedType, Bundle args) {
         if (mActiveSession != null) {
-            // XXX cancel current session.
+            mActiveSession.cancel();
+            mActiveSession = null;
         }
+        mActiveSession = new SessionConnection(intent, resolvedType, args);
         intent.addCategory(Intent.CATEGORY_VOICE);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-        mActiveSession = session;
-        mActiveInteractor = interactor;
+    }
+
+    public int deliverNewSessionLocked(int callingPid, int callingUid, IBinder token,
+            IVoiceInteractionSession session, IVoiceInteractor interactor) {
         try {
+            if (mActiveSession == null || token != mActiveSession.mToken) {
+                Slog.w(TAG, "deliverNewSession does not match active session");
+                return ActivityManager.START_CANCELED;
+            }
+            mActiveSession.mSession = session;
+            mActiveSession.mInteractor = interactor;
             return mAm.startVoiceActivity(mComponent.getPackageName(), callingPid, callingUid,
-                    intent, resolvedType, mActiveSession, mActiveInteractor,
+                    mActiveSession.mIntent, mActiveSession.mResolvedType,
+                    mActiveSession.mSession, mActiveSession.mInteractor,
                     0, null, null, null, mUser);
         } catch (RemoteException e) {
             throw new IllegalStateException("Unexpected remote error", e);
         }
     }
 
+    public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!mValid) {
+            pw.print("  NOT VALID: ");
+            if (mInfo == null) {
+                pw.println("no info");
+            } else {
+                pw.println(mInfo.getParseError());
+            }
+            return;
+        }
+        pw.print("  mComponent="); pw.println(mComponent.flattenToShortString());
+        pw.print("  Session service="); pw.println(mInfo.getSessionService());
+        pw.print("  Settings activity="); pw.println(mInfo.getSettingsActivity());
+        pw.print("  mBound="); pw.print(mBound);  pw.print(" mService="); pw.println(mService);
+        if (mActiveSession != null) {
+            pw.println("  Active session:");
+            mActiveSession.dump("    ", pw);
+        }
+    }
+
     void startLocked() {
         Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
         intent.setComponent(mComponent);
-        try {
-            ServiceInfo si = mContext.getPackageManager().getServiceInfo(mComponent, 0);
-            if (!android.Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
-                Slog.w(TAG, "Not using voice interaction service " + mComponent
-                        + ": does not require permission "
-                        + android.Manifest.permission.BIND_VOICE_INTERACTION);
-                return;
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.w(TAG, "Unable to find voice interaction service: " + mComponent, e);
-            return;
-        }
-        mContext.bindServiceAsUser(intent, mConnection,
+        mBound = mContext.bindServiceAsUser(intent, mConnection,
                 Context.BIND_AUTO_CREATE, new UserHandle(mUser));
-        mBound = true;
+        if (!mBound) {
+            Slog.w(TAG, "Failed binding to voice interaction service " + mComponent);
+        }
     }
 
     void shutdownLocked() {
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index 9c5acf9..ac0f701 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -12,10 +12,16 @@
         <service android:name="MainInteractionService"
                 android:permission="android.permission.BIND_VOICE_INTERACTION"
                 android:process=":interactor">
+            <meta-data android:name="android.voice_interaction"
+                       android:resource="@xml/interaction_service" />
             <intent-filter>
                 <action android:name="android.service.voice.VoiceInteractionService" />
             </intent-filter>
         </service>
+        <service android:name="MainInteractionSessionService"
+                android:permission="android.permission.BIND_VOICE_INTERACTION"
+                android:process=":session">
+        </service>
         <activity android:name="TestInteractionActivity" android:label="Voice Interaction Target">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/tests/VoiceInteraction/res/xml/interaction_service.xml b/tests/VoiceInteraction/res/xml/interaction_service.xml
new file mode 100644
index 0000000..45bd994d
--- /dev/null
+++ b/tests/VoiceInteraction/res/xml/interaction_service.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2014, 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.
+ */
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="com.android.test.voiceinteraction.MainInteractionSessionService" />
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 35702f1..008d97b 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -31,8 +31,7 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        startVoiceActivity(new Intent(this, TestInteractionActivity.class),
-                new MainInteractionSession(this));
+        startVoiceActivity(new Intent(this, TestInteractionActivity.class), null);
         stopSelf(startId);
         return START_NOT_STICKY;
     }
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index adc0df4..0fc563b 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -24,8 +24,11 @@
 public class MainInteractionSession extends VoiceInteractionSession {
     static final String TAG = "MainInteractionSession";
 
-    MainInteractionSession(Context context) {
+    final Bundle mArgs;
+
+    MainInteractionSession(Context context, Bundle args) {
         super(context);
+        mArgs = args;
     }
 
     @Override
@@ -42,7 +45,7 @@
     @Override
     public void onCommand(Caller caller, Request request, String command, Bundle extras) {
         Log.i(TAG, "onCommand: command=" + command + " extras=" + extras);
-        request.sendCommandResult(null);
+        request.sendCommandResult(true, null);
     }
 
     @Override
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java
new file mode 100644
index 0000000..8864d71
--- /dev/null
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.voiceinteraction;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class MainInteractionSessionService extends VoiceInteractionSessionService {
+    @Override
+    public VoiceInteractionSession onNewSession(Bundle args) {
+        return new MainInteractionSession(this, args);
+    }
+}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index 016a80e..9c772ff 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -30,28 +30,30 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        setContentView(R.layout.test_interaction);
         if (!isVoiceInteraction()) {
             Log.w(TAG, "Not running as a voice interaction!");
             finish();
             return;
         }
 
+        setContentView(R.layout.test_interaction);
+
         mInteractor = getVoiceInteractor();
-        mInteractor.startConfirmation(new VoiceInteractor.Callback() {
+        VoiceInteractor.ConfirmationRequest req = new VoiceInteractor.ConfirmationRequest(
+                "This is a confirmation", null) {
             @Override
-            public void onConfirmationResult(VoiceInteractor.Request request, boolean confirmed,
-                    Bundle result) {
-                Log.i(TAG, "Confirmation result: confirmed=" + confirmed + " result=" + result);
-                finish();
+            public void onCancel() {
+                Log.i(TAG, "Canceled!");
+                getActivity().finish();
             }
 
             @Override
-            public void onCancel(VoiceInteractor.Request request) {
-                Log.i(TAG, "Canceled!");
-                finish();
+            public void onConfirmationResult(boolean confirmed, Bundle result) {
+                Log.i(TAG, "Confirmation result: confirmed=" + confirmed + " result=" + result);
+                getActivity().finish();
             }
-        }, "This is a confirmation", null);
+        };
+        mInteractor.submitRequest(req);
     }
 
     @Override