Merge "TIF: Add the video frame rate information to TvTrackInfo" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index de84e3f2..b2106d2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2047,6 +2047,8 @@
     field public static final int TextAppearance_Material_Widget_TextView = 16974381; // 0x103022d
     field public static final int TextAppearance_Material_Widget_TextView_PopupMenu = 16974382; // 0x103022e
     field public static final int TextAppearance_Material_Widget_TextView_SpinnerItem = 16974383; // 0x103022f
+    field public static final int TextAppearance_Material_Widget_Toolbar_Subtitle = 16974569; // 0x10302e9
+    field public static final int TextAppearance_Material_Widget_Toolbar_Title = 16974568; // 0x10302e8
     field public static final int TextAppearance_Material_WindowTitle = 16974361; // 0x1030219
     field public static final int TextAppearance_Medium = 16973892; // 0x1030044
     field public static final int TextAppearance_Medium_Inverse = 16973893; // 0x1030045
@@ -16623,33 +16625,41 @@
     method public void adjustVolume(int, int);
     method public android.media.routing.MediaRouter.Delegate createMediaRouterDelegate();
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+    method public android.media.session.MediaController.AudioInfo getAudioInfo();
     method public android.os.Bundle getExtras();
     method public long getFlags();
     method public android.app.PendingIntent getLaunchActivity();
     method public android.media.MediaMetadata getMetadata();
     method public java.lang.String getPackageName();
     method public android.media.session.PlaybackState getPlaybackState();
-    method public java.util.List<android.media.session.MediaSession.Track> getQueue();
+    method public java.util.List<android.media.session.MediaSession.Item> getQueue();
     method public java.lang.CharSequence getQueueTitle();
     method public int getRatingType();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public android.media.session.MediaController.TransportControls getTransportControls();
-    method public android.media.session.MediaController.VolumeInfo getVolumeInfo();
     method public void removeCallback(android.media.session.MediaController.Callback);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
   }
 
+  public static final class MediaController.AudioInfo {
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public int getCurrentVolume();
+    method public int getMaxVolume();
+    method public int getVolumeControl();
+    method public int getVolumeType();
+  }
+
   public static abstract class MediaController.Callback {
     ctor public MediaController.Callback();
+    method public void onAudioInfoChanged(android.media.session.MediaController.AudioInfo);
     method public void onExtrasChanged(android.os.Bundle);
     method public void onMetadataChanged(android.media.MediaMetadata);
     method public void onPlaybackStateChanged(android.media.session.PlaybackState);
-    method public void onQueueChanged(java.util.List<android.media.session.MediaSession.Track>);
+    method public void onQueueChanged(java.util.List<android.media.session.MediaSession.Item>);
     method public void onQueueTitleChanged(java.lang.CharSequence);
     method public void onSessionDestroyed();
     method public void onSessionEvent(java.lang.String, android.os.Bundle);
-    method public void onVolumeInfoChanged(android.media.session.MediaController.VolumeInfo);
   }
 
   public final class MediaController.TransportControls {
@@ -16663,20 +16673,12 @@
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
+    method public void skipToItem(long);
     method public void skipToNext();
     method public void skipToPrevious();
-    method public void skipToTrack(long);
     method public void stop();
   }
 
-  public static final class MediaController.VolumeInfo {
-    method public android.media.AudioAttributes getAudioAttributes();
-    method public int getCurrentVolume();
-    method public int getMaxVolume();
-    method public int getVolumeControl();
-    method public int getVolumeType();
-  }
-
   public final class MediaSession {
     ctor public MediaSession(android.content.Context, java.lang.String);
     method public android.media.session.MediaController getController();
@@ -16696,7 +16698,7 @@
     method public void setPlaybackState(android.media.session.PlaybackState);
     method public void setPlaybackToLocal(android.media.AudioAttributes);
     method public void setPlaybackToRemote(android.media.VolumeProvider);
-    method public void setQueue(java.util.List<android.media.session.MediaSession.Track>);
+    method public void setQueue(java.util.List<android.media.session.MediaSession.Item>);
     method public void setQueueTitle(java.lang.CharSequence);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
@@ -16717,19 +16719,13 @@
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
+    method public void onSkipToItem(long);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
-    method public void onSkipToTrack(long);
     method public void onStop();
   }
 
-  public static final class MediaSession.Token implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
-  public static final class MediaSession.Track implements android.os.Parcelable {
+  public static final class MediaSession.Item implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getExtras();
     method public long getId();
@@ -16740,20 +16736,25 @@
     field public static final int UNKNOWN_ID = -1; // 0xffffffff
   }
 
-  public static final class MediaSession.Track.Builder {
-    ctor public MediaSession.Track.Builder(android.media.MediaMetadata, long, android.net.Uri);
-    method public android.media.session.MediaSession.Track build();
-    method public android.media.session.MediaSession.Track.Builder setExtras(android.os.Bundle);
+  public static final class MediaSession.Item.Builder {
+    ctor public MediaSession.Item.Builder(android.media.MediaMetadata, long, android.net.Uri);
+    method public android.media.session.MediaSession.Item build();
+    method public android.media.session.MediaSession.Item.Builder setExtras(android.os.Bundle);
+  }
+
+  public static final class MediaSession.Token implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public final class MediaSessionManager {
-    method public void addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, android.content.ComponentName);
+    method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName);
     method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName);
-    method public void removeActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener);
+    method public void removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener);
   }
 
-  public static abstract class MediaSessionManager.SessionListener {
-    ctor public MediaSessionManager.SessionListener(android.content.Context);
+  public static abstract interface MediaSessionManager.OnActiveSessionsChangedListener {
     method public abstract void onActiveSessionsChanged(java.util.List<android.media.session.MediaController>);
   }
 
@@ -16777,9 +16778,9 @@
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
+    field public static final long ACTION_SKIP_TO_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
-    field public static final long ACTION_SKIP_TO_TRACK = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
@@ -16803,7 +16804,7 @@
     method public android.media.session.PlaybackState.Builder addCustomAction(android.media.session.PlaybackState.CustomAction);
     method public android.media.session.PlaybackState build();
     method public android.media.session.PlaybackState.Builder setActions(long);
-    method public android.media.session.PlaybackState.Builder setActiveTrack(long);
+    method public android.media.session.PlaybackState.Builder setActiveItem(long);
     method public android.media.session.PlaybackState.Builder setBufferPosition(long);
     method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
     method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
@@ -17109,8 +17110,6 @@
     method public void setStreamVolume(float);
     method public void setTvInputListener(android.media.tv.TvView.TvInputListener);
     method public void tune(java.lang.String, android.net.Uri);
-    field public static final int ERROR_INPUT_DISCONNECTED = 1; // 0x1
-    field public static final int ERROR_INPUT_NOT_CONNECTED = 0; // 0x0
   }
 
   public static abstract interface TvView.OnUnhandledInputEventListener {
@@ -17120,9 +17119,10 @@
   public static abstract class TvView.TvInputListener {
     ctor public TvView.TvInputListener();
     method public void onChannelRetuned(java.lang.String, android.net.Uri);
+    method public void onConnectionFailed(java.lang.String);
     method public void onContentAllowed(java.lang.String);
     method public void onContentBlocked(java.lang.String, android.media.tv.TvContentRating);
-    method public void onError(java.lang.String, int);
+    method public void onDisconnected(java.lang.String);
     method public void onTrackSelected(java.lang.String, int, java.lang.String);
     method public void onTracksChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
     method public void onVideoAvailable(java.lang.String);
@@ -28831,12 +28831,10 @@
     method public final void setAudioModeIsVoip(boolean);
     method public final void setCallCapabilities(int);
     method public final void setCallerDisplayName(java.lang.String, int);
-    method public final void setCanceled();
     method public final void setConferenceableConnections(java.util.List<android.telecomm.Connection>);
     method public final void setConnectionService(android.telecomm.ConnectionService);
     method public final void setDialing();
     method public final void setDisconnected(int, java.lang.String);
-    method public final void setFailed(int, java.lang.String);
     method public final void setHandle(android.net.Uri, int);
     method public final void setInitialized();
     method public final void setInitializing();
@@ -28850,10 +28848,8 @@
     method public final void startActivityFromInCall(android.app.PendingIntent);
     method public static java.lang.String stateToString(int);
     field public static final int STATE_ACTIVE = 4; // 0x4
-    field public static final int STATE_CANCELED = 8; // 0x8
     field public static final int STATE_DIALING = 3; // 0x3
     field public static final int STATE_DISCONNECTED = 6; // 0x6
-    field public static final int STATE_FAILED = 7; // 0x7
     field public static final int STATE_HOLDING = 5; // 0x5
     field public static final int STATE_INITIALIZING = 0; // 0x0
     field public static final int STATE_NEW = 1; // 0x1
@@ -29643,6 +29639,7 @@
     method public int hasCarrierPrivileges();
     method public boolean hasIccCard();
     method public boolean iccCloseLogicalChannel(int);
+    method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
     method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
     method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
     method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
diff --git a/cmds/appops/Android.mk b/cmds/appops/Android.mk
new file mode 100644
index 0000000..1e15204
--- /dev/null
+++ b/cmds/appops/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2014 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := appops
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := appops
+LOCAL_SRC_FILES := appops
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
+
diff --git a/cmds/appops/MODULE_LICENSE_APACHE2 b/cmds/appops/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/appops/MODULE_LICENSE_APACHE2
diff --git a/cmds/appops/NOTICE b/cmds/appops/NOTICE
new file mode 100644
index 0000000..06a9081
--- /dev/null
+++ b/cmds/appops/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/cmds/appops/appops b/cmds/appops/appops
new file mode 100755
index 0000000..407e551
--- /dev/null
+++ b/cmds/appops/appops
@@ -0,0 +1,5 @@
+# Script to start "appwidget" on the device, which has a very rudimentary shell.
+base=/system
+export CLASSPATH=$base/framework/appops.jar
+exec app_process $base/bin com.android.commands.appops.AppOpsCommand "$@"
+
diff --git a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
new file mode 100644
index 0000000..c414f58
--- /dev/null
+++ b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
@@ -0,0 +1,137 @@
+/*
+** Copyright 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.commands.appops;
+
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.os.BaseCommand;
+
+import java.io.PrintStream;
+
+/**
+ * This class is a command line utility for manipulating AppOps permissions.
+ */
+public class AppOpsCommand extends BaseCommand {
+
+    public static void main(String[] args) {
+        new AppOpsCommand().run(args);
+    }
+
+    @Override
+    public void onShowUsage(PrintStream out) {
+        out.println("usage: adb shell appops set <PACKAGE> <OP> "
+                + "<allow|ignore|deny|default> [--user <USER_ID>]\n"
+                + "  <PACKAGE> an Android package name.\n"
+                + "  <OP>      an AppOps operation.\n"
+                + "  <USER_ID> the user id under which the package is installed. If --user is not\n"
+                + "            specified, the current user is assumed.\n");
+    }
+
+    private static final String COMMAND_SET = "set";
+
+    @Override
+    public void onRun() throws Exception {
+        String command = nextArgRequired();
+        switch (command) {
+            case COMMAND_SET:
+                runSet();
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown command '" + command + "'.");
+        }
+    }
+
+    private static final String ARGUMENT_USER = "--user";
+
+    // Modes
+    private static final String MODE_ALLOW = "allow";
+    private static final String MODE_DENY = "deny";
+    private static final String MODE_IGNORE = "ignore";
+    private static final String MODE_DEFAULT = "default";
+
+    private void runSet() throws Exception {
+        String packageName = null;
+        String op = null;
+        String mode = null;
+        int userId = UserHandle.USER_CURRENT;
+        for (String argument; (argument = nextArg()) != null;) {
+            if (ARGUMENT_USER.equals(argument)) {
+                userId = Integer.parseInt(nextArgRequired());
+            } else {
+                if (packageName == null) {
+                    packageName = argument;
+                } else if (op == null) {
+                    op = argument;
+                } else if (mode == null) {
+                    mode = argument;
+                } else {
+                    throw new IllegalArgumentException("Unsupported argument: " + argument);
+                }
+            }
+        }
+
+        if (packageName == null) {
+            throw new IllegalArgumentException("Package name not specified.");
+        } else if (op == null) {
+            throw new IllegalArgumentException("Operation not specified.");
+        } else if (mode == null) {
+            throw new IllegalArgumentException("Mode not specified.");
+        }
+
+        final int opInt = AppOpsManager.strOpToOp(op);
+        final int modeInt;
+        switch (mode) {
+            case MODE_ALLOW:
+                modeInt = AppOpsManager.MODE_ALLOWED;
+                break;
+            case MODE_DENY:
+                modeInt = AppOpsManager.MODE_ERRORED;
+                break;
+            case MODE_IGNORE:
+                modeInt = AppOpsManager.MODE_IGNORED;
+                break;
+            case MODE_DEFAULT:
+                modeInt = AppOpsManager.MODE_DEFAULT;
+                break;
+            default:
+                throw new IllegalArgumentException("Mode is invalid.");
+        }
+
+        // Parsing complete, let's execute the command.
+
+        if (userId == UserHandle.USER_CURRENT) {
+            userId = ActivityManager.getCurrentUser();
+        }
+
+        final IPackageManager pm = ActivityThread.getPackageManager();
+        final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
+                ServiceManager.getService(Context.APP_OPS_SERVICE));
+        final int uid = pm.getPackageUid(packageName, userId);
+        if (uid < 0) {
+            throw new Exception("No UID for " + packageName + " for user " + userId);
+        }
+        appOpsService.setMode(opInt, uid, packageName, modeInt);
+    }
+}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index a6b3608..0d2ad08 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1046,7 +1046,10 @@
         return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
     }
 
-    private int strOpToOp(String op) {
+    /**
+     * {@hide}
+     */
+    public static int strOpToOp(String op) {
         Integer val = sOpStrToOp.get(op);
         if (val == null) {
             throw new IllegalArgumentException("Unknown operation string: " + op);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index eadfa73..310ab76 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1558,6 +1558,26 @@
         return _enableShutterSound(enabled);
     }
 
+    /**
+     * Disable the shutter sound unconditionally.
+     *
+     * <p>
+     * This is only guaranteed to work for legacy cameras
+     * (i.e. initialized with {@link #cameraInitUnspecified}). Trying to call this on
+     * a regular camera will force a conditional check in the camera service.
+     * </p>
+     *
+     * @return {@code true} if the shutter sound state was successfully
+     *         changed. {@code false} if the shutter sound state could not be
+     *         changed. {@code true} is also returned if shutter sound playback
+     *         is already set to the requested state.
+     *
+     * @hide
+     */
+    public final boolean disableShutterSound() {
+        return _enableShutterSound(/*enabled*/false);
+    }
+
     private native final boolean _enableShutterSound(boolean enabled);
 
     /**
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index c68d8c3..5cbf109 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -56,6 +56,7 @@
  * Keep up to date with ICameraDeviceUser.aidl.
  * </p>
  */
+@SuppressWarnings("deprecation")
 public class CameraDeviceUserShim implements ICameraDeviceUser {
     private static final String TAG = "CameraDeviceUserShim";
 
@@ -259,6 +260,7 @@
                 super(l);
             }
 
+            @Override
             public void handleMessage(Message msg) {
                 try {
                     switch (msg.what) {
@@ -320,6 +322,9 @@
         // Check errors old HAL initialization
         CameraBinderDecorator.throwOnError(initErrors);
 
+        // Disable shutter sounds (this will work unconditionally) for api2 clients
+        legacyCamera.disableShutterSound();
+
         CameraInfo info = new CameraInfo();
         Camera.getCameraInfo(cameraId, info);
 
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index fbe26e5..ee0ca9c 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -1207,6 +1207,9 @@
             m.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, bestRange);
         }
 
+        // control.sceneMode -- DISABLED is always available
+        m.set(CaptureRequest.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_DISABLED);
+
         /*
          * statistics.*
          */
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 2e6b9ae..c0b7967 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -339,6 +339,11 @@
      * @see #isOutputSupportedFor(Class)
      */
     public <T> Size[] getOutputSizes(Class<T> klass) {
+        // Image reader is "supported", but never for implementation-defined formats; return empty
+        if (android.media.ImageReader.class.isAssignableFrom(klass)) {
+            return new Size[0];
+        }
+
         if (isOutputSupportedFor(klass) == false) {
             return null;
         }
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 49a307e..71df60a 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -16,13 +16,15 @@
 
 package android.net;
 
+import android.net.NetworkUtils;
 import android.os.Parcelable;
 import android.os.Parcel;
 import android.text.TextUtils;
 import android.util.Log;
 
 import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.net.Inet4Address;
+import java.util.Objects;
 
 /**
  * A simple object for retrieving the results of a DHCP request.
@@ -30,38 +32,34 @@
  * TODO - remove when DhcpInfo is deprecated.  Move the remaining api to LinkProperties.
  * @hide
  */
-public class DhcpResults implements Parcelable {
+public class DhcpResults extends StaticIpConfiguration {
     private static final String TAG = "DhcpResults";
 
-    public final LinkProperties linkProperties;
-
     public InetAddress serverAddress;
 
-    /**
-     * Vendor specific information (from RFC 2132).
-     */
+    /** Vendor specific information (from RFC 2132). */
     public String vendorInfo;
 
     public int leaseDuration;
 
     public DhcpResults() {
-        linkProperties = new LinkProperties();
+        super();
+    }
+
+    public DhcpResults(StaticIpConfiguration source) {
+        super(source);
     }
 
     /** copy constructor */
     public DhcpResults(DhcpResults source) {
-        if (source != null) {
-            linkProperties = new LinkProperties(source.linkProperties);
-            serverAddress = source.serverAddress;
-            leaseDuration = source.leaseDuration;
-            vendorInfo = source.vendorInfo;
-        } else {
-            linkProperties = new LinkProperties();
-        }
-    }
+        super(source);
 
-    public DhcpResults(LinkProperties lp) {
-        linkProperties = new LinkProperties(lp);
+        if (source != null) {
+            // All these are immutable, so no need to make copies.
+            serverAddress = source.serverAddress;
+            vendorInfo = source.vendorInfo;
+            leaseDuration = source.leaseDuration;
+        }
     }
 
     /**
@@ -70,14 +68,10 @@
      * being empty.
      */
     public void updateFromDhcpRequest(DhcpResults orig) {
-        if (orig == null || orig.linkProperties == null) return;
-        if (linkProperties.getRoutes().size() == 0) {
-            for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r);
-        }
-        if (linkProperties.getDnsServers().size() == 0) {
-            for (InetAddress d : orig.linkProperties.getDnsServers()) {
-                linkProperties.addDnsServer(d);
-            }
+        if (orig == null) return;
+        if (gateway == null) gateway = orig.gateway;
+        if (dnsServers.size() == 0) {
+            dnsServers.addAll(orig.dnsServers);
         }
     }
 
@@ -94,15 +88,14 @@
     }
 
     public void clear() {
-        linkProperties.clear();
-        serverAddress = null;
+        super.clear();
         vendorInfo = null;
         leaseDuration = 0;
     }
 
     @Override
     public String toString() {
-        StringBuffer str = new StringBuffer(linkProperties.toString());
+        StringBuffer str = new StringBuffer(super.toString());
 
         str.append(" DHCP server ").append(serverAddress);
         str.append(" Vendor info ").append(vendorInfo);
@@ -119,58 +112,19 @@
 
         DhcpResults target = (DhcpResults)obj;
 
-        if (linkProperties == null) {
-            if (target.linkProperties != null) return false;
-        } else if (!linkProperties.equals(target.linkProperties)) return false;
-        if (serverAddress == null) {
-            if (target.serverAddress != null) return false;
-        } else if (!serverAddress.equals(target.serverAddress)) return false;
-        if (vendorInfo == null) {
-            if (target.vendorInfo != null) return false;
-        } else if (!vendorInfo.equals(target.vendorInfo)) return false;
-        if (leaseDuration != target.leaseDuration) return false;
-
-        return true;
-    }
-
-    /** Implement the Parcelable interface */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
-        linkProperties.writeToParcel(dest, flags);
-
-        dest.writeInt(leaseDuration);
-
-        if (serverAddress != null) {
-            dest.writeByte((byte)1);
-            dest.writeByteArray(serverAddress.getAddress());
-        } else {
-            dest.writeByte((byte)0);
-        }
-
-        dest.writeString(vendorInfo);
+        return super.equals((StaticIpConfiguration) obj) &&
+                Objects.equals(serverAddress, target.serverAddress) &&
+                Objects.equals(vendorInfo, target.vendorInfo) &&
+                leaseDuration == target.leaseDuration;
     }
 
     /** Implement the Parcelable interface */
     public static final Creator<DhcpResults> CREATOR =
         new Creator<DhcpResults>() {
             public DhcpResults createFromParcel(Parcel in) {
-                DhcpResults prop = new DhcpResults((LinkProperties)in.readParcelable(null));
-
-                prop.leaseDuration = in.readInt();
-
-                if (in.readByte() == 1) {
-                    try {
-                        prop.serverAddress = InetAddress.getByAddress(in.createByteArray());
-                    } catch (UnknownHostException e) {}
-                }
-
-                prop.vendorInfo = in.readString();
-
-                return prop;
+                DhcpResults dhcpResults = new DhcpResults();
+                readFromParcel(dhcpResults, in);
+                return dhcpResults;
             }
 
             public DhcpResults[] newArray(int size) {
@@ -178,33 +132,39 @@
             }
         };
 
-    // Utils for jni population - false on success
-    public void setInterfaceName(String interfaceName) {
-        linkProperties.setInterfaceName(interfaceName);
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(leaseDuration);
+        NetworkUtils.parcelInetAddress(dest, serverAddress, flags);
+        dest.writeString(vendorInfo);
     }
 
-    public boolean addLinkAddress(String addrString, int prefixLength) {
-        InetAddress addr;
+    private static void readFromParcel(DhcpResults dhcpResults, Parcel in) {
+        StaticIpConfiguration.readFromParcel(dhcpResults, in);
+        dhcpResults.leaseDuration = in.readInt();
+        dhcpResults.serverAddress = NetworkUtils.unparcelInetAddress(in);
+        dhcpResults.vendorInfo = in.readString();
+    }
+
+    // Utils for jni population - false on success
+    // Not part of the superclass because they're only used by the JNI iterface to the DHCP daemon.
+    public boolean setIpAddress(String addrString, int prefixLength) {
         try {
-            addr = NetworkUtils.numericToInetAddress(addrString);
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "addLinkAddress failed with addrString " + addrString);
+            Inet4Address addr = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
+            ipAddress = new LinkAddress(addr, prefixLength);
+        } catch (IllegalArgumentException|ClassCastException e) {
+            Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength);
             return true;
         }
-
-        LinkAddress linkAddress = new LinkAddress(addr, prefixLength);
-        linkProperties.addLinkAddress(linkAddress);
-
-        RouteInfo routeInfo = new RouteInfo(linkAddress);
-        linkProperties.addRoute(routeInfo);
         return false;
     }
 
-    public boolean addGateway(String addrString) {
+    public boolean setGateway(String addrString) {
         try {
-            linkProperties.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(addrString)));
+            gateway = NetworkUtils.numericToInetAddress(addrString);
         } catch (IllegalArgumentException e) {
-            Log.e(TAG, "addGateway failed with addrString " + addrString);
+            Log.e(TAG, "setGateway failed with addrString " + addrString);
             return true;
         }
         return false;
@@ -213,7 +173,7 @@
     public boolean addDns(String addrString) {
         if (TextUtils.isEmpty(addrString) == false) {
             try {
-                linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString));
+                dnsServers.add(NetworkUtils.numericToInetAddress(addrString));
             } catch (IllegalArgumentException e) {
                 Log.e(TAG, "addDns failed with addrString " + addrString);
                 return true;
@@ -241,6 +201,6 @@
     }
 
     public void setDomains(String domains) {
-        linkProperties.setDomains(domains);
+        domains = domains;
     }
 }
diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
index 608ca28..d965f27 100644
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -21,7 +21,6 @@
 import android.net.IpConfiguration;
 import android.net.IpConfiguration.IpAssignment;
 import android.net.IpConfiguration.ProxySettings;
-import android.net.LinkProperties;
 import android.os.RemoteException;
 
 /**
@@ -52,16 +51,12 @@
      */
     public IpConfiguration getConfiguration() {
         if (mService == null) {
-            return new IpConfiguration(IpAssignment.UNASSIGNED,
-                                       ProxySettings.UNASSIGNED,
-                                       new LinkProperties());
+            return new IpConfiguration();
         }
         try {
             return mService.getConfiguration();
         } catch (RemoteException e) {
-            return new IpConfiguration(IpAssignment.UNASSIGNED,
-                                       ProxySettings.UNASSIGNED,
-                                       new LinkProperties());
+            return new IpConfiguration();
         }
     }
 
diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java
index 4730bab..fe69f296 100644
--- a/core/java/android/net/IpConfiguration.java
+++ b/core/java/android/net/IpConfiguration.java
@@ -16,7 +16,7 @@
 
 package android.net;
 
-import android.net.LinkProperties;
+import android.net.StaticIpConfiguration;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -31,7 +31,7 @@
 
     public enum IpAssignment {
         /* Use statically configured IP settings. Configuration can be accessed
-         * with linkProperties */
+         * with staticIpConfiguration */
         STATIC,
         /* Use dynamically configured IP settigns */
         DHCP,
@@ -42,12 +42,14 @@
 
     public IpAssignment ipAssignment;
 
+    public StaticIpConfiguration staticIpConfiguration;
+
     public enum ProxySettings {
         /* No proxy is to be used. Any existing proxy settings
          * should be cleared. */
         NONE,
         /* Use statically configured proxy. Configuration can be accessed
-         * with linkProperties */
+         * with httpProxy. */
         STATIC,
         /* no proxy details are assigned, this is used to indicate
          * that any existing proxy settings should be retained */
@@ -59,30 +61,69 @@
 
     public ProxySettings proxySettings;
 
-    public LinkProperties linkProperties;
+    public ProxyInfo httpProxy;
 
-    public IpConfiguration(IpConfiguration source) {
-        if (source != null) {
-            ipAssignment = source.ipAssignment;
-            proxySettings = source.proxySettings;
-            linkProperties = new LinkProperties(source.linkProperties);
-        } else {
-            ipAssignment = IpAssignment.UNASSIGNED;
-            proxySettings = ProxySettings.UNASSIGNED;
-            linkProperties = new LinkProperties();
-        }
+    private void init(IpAssignment ipAssignment,
+                      ProxySettings proxySettings,
+                      StaticIpConfiguration staticIpConfiguration,
+                      ProxyInfo httpProxy) {
+        this.ipAssignment = ipAssignment;
+        this.proxySettings = proxySettings;
+        this.staticIpConfiguration = (staticIpConfiguration == null) ?
+                null : new StaticIpConfiguration(staticIpConfiguration);
+        this.httpProxy = (httpProxy == null) ?
+                null : new ProxyInfo(httpProxy);
     }
 
     public IpConfiguration() {
-         this(null);
+        init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
     }
 
     public IpConfiguration(IpAssignment ipAssignment,
                            ProxySettings proxySettings,
-                           LinkProperties linkProperties) {
+                           StaticIpConfiguration staticIpConfiguration,
+                           ProxyInfo httpProxy) {
+        init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
+    }
+
+    public IpConfiguration(IpConfiguration source) {
+        this();
+        if (source != null) {
+            init(source.ipAssignment, source.proxySettings,
+                 source.staticIpConfiguration, source.httpProxy);
+        }
+    }
+
+    public IpAssignment getIpAssignment() {
+        return ipAssignment;
+    }
+
+    public void setIpAssignment(IpAssignment ipAssignment) {
         this.ipAssignment = ipAssignment;
+    }
+
+    public StaticIpConfiguration getStaticIpConfiguration() {
+        return staticIpConfiguration;
+    }
+
+    public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
+        this.staticIpConfiguration = staticIpConfiguration;
+    }
+
+    public ProxySettings getProxySettings() {
+        return proxySettings;
+    }
+
+    public void setProxySettings(ProxySettings proxySettings) {
         this.proxySettings = proxySettings;
-        this.linkProperties = new LinkProperties(linkProperties);
+    }
+
+    public ProxyInfo getHttpProxy() {
+        return httpProxy;
+    }
+
+    public void setHttpProxy(ProxyInfo httpProxy) {
+        this.httpProxy = httpProxy;
     }
 
     @Override
@@ -90,10 +131,16 @@
         StringBuilder sbuf = new StringBuilder();
         sbuf.append("IP assignment: " + ipAssignment.toString());
         sbuf.append("\n");
+        if (staticIpConfiguration != null) {
+            sbuf.append("Static configuration: " + staticIpConfiguration.toString());
+            sbuf.append("\n");
+        }
         sbuf.append("Proxy settings: " + proxySettings.toString());
         sbuf.append("\n");
-        sbuf.append(linkProperties.toString());
-        sbuf.append("\n");
+        if (httpProxy != null) {
+            sbuf.append("HTTP proxy: " + httpProxy.toString());
+            sbuf.append("\n");
+        }
 
         return sbuf.toString();
     }
@@ -111,14 +158,16 @@
         IpConfiguration other = (IpConfiguration) o;
         return this.ipAssignment == other.ipAssignment &&
                 this.proxySettings == other.proxySettings &&
-                Objects.equals(this.linkProperties, other.linkProperties);
+                Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) &&
+                Objects.equals(this.httpProxy, other.httpProxy);
     }
 
     @Override
     public int hashCode() {
-        return 13 + (linkProperties != null ? linkProperties.hashCode() : 0) +
+        return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) +
                17 * ipAssignment.ordinal() +
-               47 * proxySettings.ordinal();
+               47 * proxySettings.ordinal() +
+               83 * httpProxy.hashCode();
     }
 
     /** Implement the Parcelable interface */
@@ -130,7 +179,8 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(ipAssignment.name());
         dest.writeString(proxySettings.name());
-        dest.writeParcelable(linkProperties, flags);
+        dest.writeParcelable(staticIpConfiguration, flags);
+        dest.writeParcelable(httpProxy, flags);
     }
 
     /** Implement the Parcelable interface */
@@ -140,7 +190,8 @@
                 IpConfiguration config = new IpConfiguration();
                 config.ipAssignment = IpAssignment.valueOf(in.readString());
                 config.proxySettings = ProxySettings.valueOf(in.readString());
-                config.linkProperties = in.readParcelable(null);
+                config.staticIpConfiguration = in.readParcelable(null);
+                config.httpProxy = in.readParcelable(null);
                 return config;
             }
 
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 663aa15..54d8676 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -23,6 +23,7 @@
 import java.util.Collection;
 import java.util.Locale;
 
+import android.os.Parcel;
 import android.util.Log;
 import android.util.Pair;
 
@@ -203,6 +204,32 @@
     }
 
     /**
+     * Writes an InetAddress to a parcel. The address may be null. This is likely faster than
+     * calling writeSerializable.
+     */
+    protected static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) {
+        byte[] addressArray = (address != null) ? address.getAddress() : null;
+        parcel.writeByteArray(addressArray);
+    }
+
+    /**
+     * Reads an InetAddress from a parcel. Returns null if the address that was written was null
+     * or if the data is invalid.
+     */
+    protected static InetAddress unparcelInetAddress(Parcel in) {
+        byte[] addressArray = in.createByteArray();
+        if (addressArray == null) {
+            return null;
+        }
+        try {
+            return InetAddress.getByAddress(addressArray);
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+
+    /**
      *  Masks a raw IP address byte array with the specified prefix length.
      */
     public static void maskRawAddress(byte[] array, int prefixLength) {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
new file mode 100644
index 0000000..5a273cf
--- /dev/null
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -0,0 +1,194 @@
+/*
+ * 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.net;
+
+import android.net.LinkAddress;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Class that describes static IP configuration.
+ *
+ * This class is different from LinkProperties because it represents
+ * configuration intent. The general contract is that if we can represent
+ * a configuration here, then we should be able to configure it on a network.
+ * The intent is that it closely match the UI we have for configuring networks.
+ *
+ * In contrast, LinkProperties represents current state. It is much more
+ * expressive. For example, it supports multiple IP addresses, multiple routes,
+ * stacked interfaces, and so on. Because LinkProperties is so expressive,
+ * using it to represent configuration intent as well as current state causes
+ * problems. For example, we could unknowingly save a configuration that we are
+ * not in fact capable of applying, or we could save a configuration that the
+ * UI cannot display, which has the potential for malicious code to hide
+ * hostile or unexpected configuration from the user: see, for example,
+ * http://b/12663469 and http://b/16893413 .
+ *
+ * @hide
+ */
+public class StaticIpConfiguration implements Parcelable {
+    public LinkAddress ipAddress;
+    public InetAddress gateway;
+    public final ArrayList<InetAddress> dnsServers;
+    public String domains;
+
+    public StaticIpConfiguration() {
+        dnsServers = new ArrayList<InetAddress>();
+    }
+
+    public StaticIpConfiguration(StaticIpConfiguration source) {
+        this();
+        if (source != null) {
+            // All of these except dnsServers are immutable, so no need to make copies.
+            ipAddress = source.ipAddress;
+            gateway = source.gateway;
+            dnsServers.addAll(source.dnsServers);
+            domains = source.domains;
+        }
+    }
+
+    public void clear() {
+        ipAddress = null;
+        gateway = null;
+        dnsServers.clear();
+        domains = null;
+    }
+
+    /**
+     * Returns the network routes specified by this object. Will typically include a
+     * directly-connected route for the IP address's local subnet and a default route.
+     */
+    public List<RouteInfo> getRoutes(String iface) {
+        List<RouteInfo> routes = new ArrayList<RouteInfo>(2);
+        if (ipAddress != null) {
+            routes.add(new RouteInfo(ipAddress, null, iface));
+        }
+        if (gateway != null) {
+            routes.add(new RouteInfo((LinkAddress) null, gateway, iface));
+        }
+        return routes;
+    }
+
+    /**
+     * Returns a LinkProperties object expressing the data in this object. Note that the information
+     * contained in the LinkProperties will not be a complete picture of the link's configuration,
+     * because any configuration information that is obtained dynamically by the network (e.g.,
+     * IPv6 configuration) will not be included.
+     */
+    public LinkProperties toLinkProperties(String iface) {
+        LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName(iface);
+        if (ipAddress != null) {
+            lp.addLinkAddress(ipAddress);
+        }
+        for (RouteInfo route : getRoutes(iface)) {
+            lp.addRoute(route);
+        }
+        for (InetAddress dns : dnsServers) {
+            lp.addDnsServer(dns);
+        }
+        return lp;
+    }
+
+    public String toString() {
+        StringBuffer str = new StringBuffer();
+
+        str.append("IP address ");
+        if (ipAddress != null ) str.append(ipAddress).append(" ");
+
+        str.append("Gateway ");
+        if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
+
+        str.append(" DNS servers: [");
+        for (InetAddress dnsServer : dnsServers) {
+            str.append(" ").append(dnsServer.getHostAddress());
+        }
+
+        str.append(" ] Domains");
+        if (domains != null) str.append(domains);
+        return str.toString();
+    }
+
+    public int hashCode() {
+        int result = 13;
+        result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
+        result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
+        result = 47 * result + (domains == null ? 0 : domains.hashCode());
+        result = 47 * result + dnsServers.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof StaticIpConfiguration)) return false;
+
+        StaticIpConfiguration other = (StaticIpConfiguration) obj;
+
+        return other != null &&
+                Objects.equals(ipAddress, other.ipAddress) &&
+                Objects.equals(gateway, other.gateway) &&
+                dnsServers.equals(other.dnsServers) &&
+                Objects.equals(domains, other.domains);
+    }
+
+    /** Implement the Parcelable interface */
+    public static Creator<StaticIpConfiguration> CREATOR =
+        new Creator<StaticIpConfiguration>() {
+            public StaticIpConfiguration createFromParcel(Parcel in) {
+                StaticIpConfiguration s = new StaticIpConfiguration();
+                readFromParcel(s, in);
+                return s;
+            }
+
+            public StaticIpConfiguration[] newArray(int size) {
+                return new StaticIpConfiguration[size];
+            }
+        };
+
+    /** Implement the Parcelable interface */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(ipAddress, flags);
+        NetworkUtils.parcelInetAddress(dest, gateway, flags);
+        dest.writeInt(dnsServers.size());
+        for (InetAddress dnsServer : dnsServers) {
+            NetworkUtils.parcelInetAddress(dest, dnsServer, flags);
+        }
+    }
+
+    protected static void readFromParcel(StaticIpConfiguration s, Parcel in) {
+        s.ipAddress = in.readParcelable(null);
+        s.gateway = NetworkUtils.unparcelInetAddress(in);
+        s.dnsServers.clear();
+        int size = in.readInt();
+        for (int i = 0; i < size; i++) {
+            s.dnsServers.add(NetworkUtils.unparcelInetAddress(in));
+        }
+    }
+}
diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java
index efcbdb3..6246cbe 100644
--- a/core/java/android/transition/ChangeBounds.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -16,13 +16,11 @@
 
 package android.transition;
 
-import android.animation.TypeConverter;
 import android.content.Context;
 import android.graphics.PointF;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.RectEvaluator;
@@ -119,9 +117,11 @@
         values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
                 view.getRight(), view.getBottom()));
         values.values.put(PROPNAME_PARENT, values.view.getParent());
-        values.view.getLocationInWindow(tempLocation);
-        values.values.put(PROPNAME_WINDOW_X, tempLocation[0]);
-        values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]);
+        if (mReparent) {
+            values.view.getLocationInWindow(tempLocation);
+            values.values.put(PROPNAME_WINDOW_X, tempLocation[0]);
+            values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]);
+        }
     }
 
     @Override
@@ -134,6 +134,19 @@
         captureValues(transitionValues);
     }
 
+    private boolean parentMatches(View startParent, View endParent) {
+        boolean parentMatches = true;
+        if (mReparent) {
+            TransitionValues endValues = getMatchedTransitionValues(startParent, true);
+            if (endValues == null) {
+                parentMatches = startParent == endParent;
+            } else {
+                parentMatches = endParent == endValues.view;
+            }
+        }
+        return parentMatches;
+    }
+
     @Override
     public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
@@ -148,13 +161,7 @@
             return null;
         }
         final View view = endValues.view;
-        boolean parentsEqual = (startParent == endParent) ||
-                (startParent.getId() == endParent.getId());
-        // TODO: Might want reparenting to be separate/subclass transition, or at least
-        // triggered by a property on ChangeBounds. Otherwise, we're forcing the requirement that
-        // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
-        // of reparenting the views.
-        if (!mReparent || parentsEqual) {
+        if (parentMatches(startParent, endParent)) {
             Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
             Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
             int startLeft = startBounds.left;
diff --git a/core/java/android/transition/ChangeImageTransform.java b/core/java/android/transition/ChangeImageTransform.java
index 2b26756..4b230eb 100644
--- a/core/java/android/transition/ChangeImageTransform.java
+++ b/core/java/android/transition/ChangeImageTransform.java
@@ -182,6 +182,7 @@
             if (endMatrix == null) {
                 endMatrix = Matrix.IDENTITY_MATRIX;
             }
+            ANIMATED_TRANSFORM_PROPERTY.set(imageView, startMatrix);
             animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
         }
         return animator;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 2fa8d2a..0d32d40 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -192,6 +192,8 @@
     private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
     TransitionSet mParent = null;
     private int[] mMatchOrder = DEFAULT_MATCH_ORDER;
+    ArrayList<TransitionValues> mStartValuesList; // only valid after playTransition starts
+    ArrayList<TransitionValues> mEndValuesList; // only valid after playTransitions starts
 
     // Per-animator information used for later canceling when future transitions overlap
     private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators =
@@ -518,32 +520,28 @@
     }
 
     /**
-     * Match start/end values by View instance. Adds matched values to startValuesList
-     * and endValuesList and removes them from unmatchedStart and unmatchedEnd.
+     * Match start/end values by View instance. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd.
      */
-    private void matchInstances(ArrayList<TransitionValues> startValuesList,
-            ArrayList<TransitionValues> endValuesList,
-            ArrayMap<View, TransitionValues> unmatchedStart,
+    private void matchInstances(ArrayMap<View, TransitionValues> unmatchedStart,
             ArrayMap<View, TransitionValues> unmatchedEnd) {
         for (int i = unmatchedStart.size() - 1; i >= 0; i--) {
             View view = unmatchedStart.keyAt(i);
             TransitionValues end = unmatchedEnd.remove(view);
             if (end != null) {
                 TransitionValues start = unmatchedStart.removeAt(i);
-                startValuesList.add(start);
-                endValuesList.add(end);
+                mStartValuesList.add(start);
+                mEndValuesList.add(end);
             }
         }
     }
 
     /**
-     * Match start/end values by Adapter item ID. Adds matched values to startValuesList
-     * and endValuesList and removes them from unmatchedStart and unmatchedEnd, using
+     * Match start/end values by Adapter item ID. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
      * startItemIds and endItemIds as a guide for which Views have unique item IDs.
      */
-    private void matchItemIds(ArrayList<TransitionValues> startValuesList,
-            ArrayList<TransitionValues> endValuesList,
-            ArrayMap<View, TransitionValues> unmatchedStart,
+    private void matchItemIds(ArrayMap<View, TransitionValues> unmatchedStart,
             ArrayMap<View, TransitionValues> unmatchedEnd,
             LongSparseArray<View> startItemIds, LongSparseArray<View> endItemIds) {
         int numStartIds = startItemIds.size();
@@ -555,8 +553,8 @@
                     TransitionValues startValues = unmatchedStart.get(startView);
                     TransitionValues endValues = unmatchedEnd.get(endView);
                     if (startValues != null && endValues != null) {
-                        startValuesList.add(startValues);
-                        endValuesList.add(endValues);
+                        mStartValuesList.add(startValues);
+                        mEndValuesList.add(endValues);
                         unmatchedStart.remove(startView);
                         unmatchedEnd.remove(endView);
                     }
@@ -566,13 +564,11 @@
     }
 
     /**
-     * Match start/end values by Adapter view ID. Adds matched values to startValuesList
-     * and endValuesList and removes them from unmatchedStart and unmatchedEnd, using
+     * Match start/end values by Adapter view ID. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
      * startIds and endIds as a guide for which Views have unique IDs.
      */
-    private void matchIds(ArrayList<TransitionValues> startValuesList,
-            ArrayList<TransitionValues> endValuesList,
-            ArrayMap<View, TransitionValues> unmatchedStart,
+    private void matchIds(ArrayMap<View, TransitionValues> unmatchedStart,
             ArrayMap<View, TransitionValues> unmatchedEnd,
             SparseArray<View> startIds, SparseArray<View> endIds) {
         int numStartIds = startIds.size();
@@ -584,8 +580,8 @@
                     TransitionValues startValues = unmatchedStart.get(startView);
                     TransitionValues endValues = unmatchedEnd.get(endView);
                     if (startValues != null && endValues != null) {
-                        startValuesList.add(startValues);
-                        endValuesList.add(endValues);
+                        mStartValuesList.add(startValues);
+                        mEndValuesList.add(endValues);
                         unmatchedStart.remove(startView);
                         unmatchedEnd.remove(endView);
                     }
@@ -595,13 +591,11 @@
     }
 
     /**
-     * Match start/end values by Adapter transitionName. Adds matched values to startValuesList
-     * and endValuesList and removes them from unmatchedStart and unmatchedEnd, using
+     * Match start/end values by Adapter transitionName. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
      * startNames and endNames as a guide for which Views have unique transitionNames.
      */
-    private void matchNames(ArrayList<TransitionValues> startValuesList,
-            ArrayList<TransitionValues> endValuesList,
-            ArrayMap<View, TransitionValues> unmatchedStart,
+    private void matchNames(ArrayMap<View, TransitionValues> unmatchedStart,
             ArrayMap<View, TransitionValues> unmatchedEnd,
             ArrayMap<String, View> startNames, ArrayMap<String, View> endNames) {
         int numStartNames = startNames.size();
@@ -613,8 +607,8 @@
                     TransitionValues startValues = unmatchedStart.get(startView);
                     TransitionValues endValues = unmatchedEnd.get(endView);
                     if (startValues != null && endValues != null) {
-                        startValuesList.add(startValues);
-                        endValuesList.add(endValues);
+                        mStartValuesList.add(startValues);
+                        mEndValuesList.add(endValues);
                         unmatchedStart.remove(startView);
                         unmatchedEnd.remove(endView);
                     }
@@ -624,30 +618,26 @@
     }
 
     /**
-     * Adds all values from unmatchedStart and unmatchedEnd to startValuesList and endValuesList,
+     * Adds all values from unmatchedStart and unmatchedEnd to mStartValuesList and mEndValuesList,
      * assuming that there is no match between values in the list.
      */
-    private void addUnmatched(ArrayList<TransitionValues> startValuesList,
-            ArrayList<TransitionValues> endValuesList,
-            ArrayMap<View, TransitionValues> unmatchedStart,
+    private void addUnmatched(ArrayMap<View, TransitionValues> unmatchedStart,
             ArrayMap<View, TransitionValues> unmatchedEnd) {
         // Views that only exist in the start Scene
         for (int i = 0; i < unmatchedStart.size(); i++) {
-            startValuesList.add(unmatchedStart.valueAt(i));
-            endValuesList.add(null);
+            mStartValuesList.add(unmatchedStart.valueAt(i));
+            mEndValuesList.add(null);
         }
 
         // Views that only exist in the end Scene
         for (int i = 0; i < unmatchedEnd.size(); i++) {
-            endValuesList.add(unmatchedEnd.valueAt(i));
-            startValuesList.add(null);
+            mEndValuesList.add(unmatchedEnd.valueAt(i));
+            mStartValuesList.add(null);
         }
     }
 
     private void matchStartAndEnd(TransitionValuesMaps startValues,
-            TransitionValuesMaps endValues,
-            ArrayList<TransitionValues> startValuesList,
-            ArrayList<TransitionValues> endValuesList) {
+            TransitionValuesMaps endValues) {
         ArrayMap<View, TransitionValues> unmatchedStart =
                 new ArrayMap<View, TransitionValues>(startValues.viewValues);
         ArrayMap<View, TransitionValues> unmatchedEnd =
@@ -656,23 +646,23 @@
         for (int i = 0; i < mMatchOrder.length; i++) {
             switch (mMatchOrder[i]) {
                 case MATCH_INSTANCE:
-                    matchInstances(startValuesList, endValuesList, unmatchedStart, unmatchedEnd);
+                    matchInstances(unmatchedStart, unmatchedEnd);
                     break;
                 case MATCH_NAME:
-                    matchNames(startValuesList, endValuesList, unmatchedStart, unmatchedEnd,
+                    matchNames(unmatchedStart, unmatchedEnd,
                             startValues.nameValues, endValues.nameValues);
                     break;
                 case MATCH_ID:
-                    matchIds(startValuesList, endValuesList, unmatchedStart, unmatchedEnd,
+                    matchIds(unmatchedStart, unmatchedEnd,
                             startValues.idValues, endValues.idValues);
                     break;
                 case MATCH_ITEM_ID:
-                    matchItemIds(startValuesList, endValuesList, unmatchedStart, unmatchedEnd,
+                    matchItemIds(unmatchedStart, unmatchedEnd,
                             startValues.itemIdValues, endValues.itemIdValues);
                     break;
             }
         }
-        addUnmatched(startValuesList, endValuesList, unmatchedStart, unmatchedEnd);
+        addUnmatched(unmatchedStart, unmatchedEnd);
     }
 
     /**
@@ -687,19 +677,17 @@
      * @hide
      */
     protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
-            TransitionValuesMaps endValues) {
+            TransitionValuesMaps endValues, ArrayList<TransitionValues> startValuesList,
+            ArrayList<TransitionValues> endValuesList) {
         if (DBG) {
             Log.d(LOG_TAG, "createAnimators() for " + this);
         }
-        ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>();
-        ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>();
-        matchStartAndEnd(startValues, endValues, startValuesList, endValuesList);
-
         ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
         long minStartDelay = Long.MAX_VALUE;
         int minAnimator = mAnimators.size();
         SparseLongArray startDelays = new SparseLongArray();
-        for (int i = 0; i < startValuesList.size(); ++i) {
+        int startValuesListCount = startValuesList.size();
+        for (int i = 0; i < startValuesListCount; ++i) {
             TransitionValues start = startValuesList.get(i);
             TransitionValues end = endValuesList.get(i);
             // Only bother trying to animate with valid values that differ between start/end
@@ -1523,11 +1511,13 @@
             mStartValues.idValues.clear();
             mStartValues.itemIdValues.clear();
             mStartValues.nameValues.clear();
+            mStartValuesList = null;
         } else {
             mEndValues.viewValues.clear();
             mEndValues.idValues.clear();
             mEndValues.itemIdValues.clear();
             mEndValues.nameValues.clear();
+            mEndValuesList = null;
         }
     }
 
@@ -1613,6 +1603,45 @@
     }
 
     /**
+     * Find the matched start or end value for a given View. This is only valid
+     * after playTransition starts. For example, it will be valid in
+     * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}, but not
+     * in {@link #captureStartValues(TransitionValues)}.
+     *
+     * @param view The view to find the match for.
+     * @param viewInStart Is View from the start values or end values.
+     * @return The matching TransitionValues for view in either start or end values, depending
+     * on viewInStart or null if there is no match for the given view.
+     */
+    TransitionValues getMatchedTransitionValues(View view, boolean viewInStart) {
+        if (mParent != null) {
+            return mParent.getMatchedTransitionValues(view, viewInStart);
+        }
+        ArrayList<TransitionValues> lookIn = viewInStart ? mStartValuesList : mEndValuesList;
+        if (lookIn == null) {
+            return null;
+        }
+        int count = lookIn.size();
+        int index = -1;
+        for (int i = 0; i < count; i++) {
+            TransitionValues values = lookIn.get(i);
+            if (values == null) {
+                return null;
+            }
+            if (values.view == view) {
+                index = i;
+                break;
+            }
+        }
+        TransitionValues values = null;
+        if (index >= 0) {
+            ArrayList<TransitionValues> matchIn = viewInStart ? mEndValuesList : mStartValuesList;
+            values = matchIn.get(index);
+        }
+        return values;
+    }
+
+    /**
      * Pauses this transition, sending out calls to {@link
      * TransitionListener#onTransitionPause(Transition)} to all listeners
      * and pausing all running animators started by this transition.
@@ -1684,6 +1713,10 @@
      * runAnimations() to actually start the animations.
      */
     void playTransition(ViewGroup sceneRoot) {
+        mStartValuesList = new ArrayList<TransitionValues>();
+        mEndValuesList = new ArrayList<TransitionValues>();
+        matchStartAndEnd(mStartValues, mEndValues);
+
         ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
         int numOldAnims = runningAnimators.size();
         WindowId windowId = sceneRoot.getWindowId();
@@ -1694,7 +1727,7 @@
                 if (oldInfo != null && oldInfo.view != null && oldInfo.windowId == windowId) {
                     TransitionValues oldValues = oldInfo.values;
                     View oldView = oldInfo.view;
-                    TransitionValues newValues = mEndValues.viewValues.get(oldView);
+                    TransitionValues newValues = getMatchedTransitionValues(oldView, true);
                     boolean cancel = oldInfo.transition.areValuesChanged(oldValues, newValues);
                     if (cancel) {
                         if (anim.isRunning() || anim.isStarted()) {
@@ -1713,7 +1746,7 @@
             }
         }
 
-        createAnimators(sceneRoot, mStartValues, mEndValues);
+        createAnimators(sceneRoot, mStartValues, mEndValues, mStartValuesList, mEndValuesList);
         runAnimators();
     }
 
@@ -2055,6 +2088,8 @@
             clone.mAnimators = new ArrayList<Animator>();
             clone.mStartValues = new TransitionValuesMaps();
             clone.mEndValues = new TransitionValuesMaps();
+            clone.mStartValuesList = null;
+            clone.mEndValuesList = null;
         } catch (CloneNotSupportedException e) {}
 
         return clone;
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 68af2d1..f6499ae 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -386,11 +386,13 @@
      */
     @Override
     protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
-            TransitionValuesMaps endValues) {
+            TransitionValuesMaps endValues, ArrayList<TransitionValues> startValuesList,
+            ArrayList<TransitionValues> endValuesList) {
         startValues = removeExcludes(startValues);
         endValues = removeExcludes(endValues);
         for (Transition childTransition : mTransitions) {
-            childTransition.createAnimators(sceneRoot, startValues, endValues);
+            childTransition.createAnimators(sceneRoot, startValues, endValues, startValuesList,
+                    endValuesList);
         }
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cec7e63..3adc41a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13831,6 +13831,7 @@
                     } else {
                         draw(canvas);
                     }
+                    drawAccessibilityFocus(canvas);
                 }
             } finally {
                 renderNode.end(canvas);
@@ -14125,6 +14126,7 @@
             } else {
                 draw(canvas);
             }
+            drawAccessibilityFocus(canvas);
 
             canvas.restoreToCount(restoreCount);
             canvas.setBitmap(null);
@@ -14199,6 +14201,7 @@
         } else {
             draw(canvas);
         }
+        drawAccessibilityFocus(canvas);
 
         mPrivateFlags = flags;
 
@@ -14792,9 +14795,13 @@
                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                         dispatchDraw(canvas);
+                        if (mOverlay != null && !mOverlay.isEmpty()) {
+                            mOverlay.getOverlayView().draw(canvas);
+                        }
                     } else {
                         draw(canvas);
                     }
+                    drawAccessibilityFocus(canvas);
                 } else {
                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                     ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
@@ -15046,6 +15053,45 @@
     }
 
     /**
+     * Draws the accessibility focus rect onto the specified canvas.
+     *
+     * @param canvas Canvas on which to draw the focus rect
+     */
+    private void drawAccessibilityFocus(Canvas canvas) {
+        if (mAttachInfo == null) {
+            return;
+        }
+
+        final Rect bounds = mAttachInfo.mTmpInvalRect;
+        final ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot == null || viewRoot.getAccessibilityFocusedHost() != this) {
+            return;
+        }
+
+        final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
+        if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
+            return;
+        }
+
+        final Drawable drawable = viewRoot.getAccessibilityFocusedDrawable();
+        if (drawable == null) {
+            return;
+        }
+
+        final AccessibilityNodeInfo virtualView = viewRoot.getAccessibilityFocusedVirtualView();
+        if (virtualView != null) {
+            virtualView.getBoundsInParent(bounds);
+        } else {
+            bounds.set(0, 0, mRight - mLeft, mBottom - mTop);
+        }
+
+        canvas.translate(mScrollX, mScrollY);
+        drawable.setBounds(bounds);
+        drawable.draw(canvas);
+        canvas.translate(-mScrollX, -mScrollY);
+    }
+
+    /**
      * Draws the background onto the specified canvas.
      *
      * @param canvas Canvas on which to draw the background
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 92e0245..bb469a3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2244,7 +2244,6 @@
             canvas.drawHardwareLayer(mResizeBuffer, mHardwareXOffset, mHardwareYOffset,
                     mResizePaint);
         }
-        drawAccessibilityFocusedDrawableIfNeeded(canvas);
     }
 
     /**
@@ -2462,25 +2461,9 @@
                 if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
                     mHardwareYOffset = yOffset;
                     mHardwareXOffset = xOffset;
-                    invalidateRoot = true;
-                }
-                mResizeAlpha = resizeAlpha;
-
-                if (!invalidateRoot) {
-                    // If accessibility focus moved, invalidate the root.
-                    final Drawable drawable = mAttachInfo.mAccessibilityFocusDrawable;
-                    if (drawable != null) {
-                        final Rect bounds = mAttachInfo.mTmpInvalRect;
-                        if (getAccessibilityFocusedRect(bounds)
-                                && !bounds.equals(drawable.getBounds())) {
-                            invalidateRoot = true;
-                        }
-                    }
-                }
-
-                if (invalidateRoot) {
                     mAttachInfo.mHardwareRenderer.invalidateRoot();
                 }
+                mResizeAlpha = resizeAlpha;
 
                 dirty.setEmpty();
 
@@ -2600,8 +2583,6 @@
                 attachInfo.mSetIgnoreDirtyState = false;
 
                 mView.draw(canvas);
-
-                drawAccessibilityFocusedDrawableIfNeeded(canvas);
             } finally {
                 if (!attachInfo.mSetIgnoreDirtyState) {
                     // Only clear the flag if it was not set during the mView.draw() call
@@ -2625,54 +2606,7 @@
         return true;
     }
 
-    /**
-     * We want to draw a highlight around the current accessibility focused.
-     * Since adding a style for all possible view is not a viable option we
-     * have this specialized drawing method.
-     *
-     * Note: We are doing this here to be able to draw the highlight for
-     *       virtual views in addition to real ones.
-     *
-     * @param canvas The canvas on which to draw.
-     */
-    private void drawAccessibilityFocusedDrawableIfNeeded(Canvas canvas) {
-        final Rect bounds = mAttachInfo.mTmpInvalRect;
-        if (getAccessibilityFocusedRect(bounds)) {
-            final Drawable drawable = getAccessibilityFocusedDrawable();
-            if (drawable != null) {
-                drawable.setBounds(bounds);
-                drawable.draw(canvas);
-            }
-        }
-    }
-
-    private boolean getAccessibilityFocusedRect(Rect bounds) {
-        final AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
-        if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
-            return false;
-        }
-
-        final View host = mAccessibilityFocusedHost;
-        if (host == null || host.mAttachInfo == null) {
-            return false;
-        }
-
-        final AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
-        if (provider == null) {
-            host.getBoundsOnScreen(bounds);
-        } else if (mAccessibilityFocusedVirtualView != null) {
-            mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
-        } else {
-            return false;
-        }
-
-        final AttachInfo attachInfo = mAttachInfo;
-        bounds.offset(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
-        bounds.intersect(0, 0, attachInfo.mViewRootImpl.mWidth, attachInfo.mViewRootImpl.mHeight);
-        return true;
-    }
-
-    private Drawable getAccessibilityFocusedDrawable() {
+    Drawable getAccessibilityFocusedDrawable() {
         // Lazily load the accessibility focus drawable.
         if (mAttachInfo.mAccessibilityFocusDrawable == null) {
             final TypedValue value = new TypedValue();
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 4dd7e07..23f911c 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1501,7 +1501,7 @@
                     mRules[ALIGN_PARENT_START] = 0;
                 }
 
-                if (mRules[ALIGN_PARENT_RIGHT] == 0) {
+                if (mRules[ALIGN_PARENT_END] != 0) {
                     if (mRules[ALIGN_PARENT_RIGHT] == 0) {
                         // "right" rule is not defined but "end" rule is: use the "end" rule as the
                         // "right" rule
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 32cf286..5bd38f3 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -69,9 +69,8 @@
  */
 static struct fieldIds {
     jmethodID clear;
-    jmethodID setInterfaceName;
-    jmethodID addLinkAddress;
-    jmethodID addGateway;
+    jmethodID setIpAddress;
+    jmethodID setGateway;
     jmethodID addDns;
     jmethodID setDomains;
     jmethodID setServerAddress;
@@ -130,21 +129,16 @@
     if (result == 0) {
         env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
 
-        // set mIfaceName
-        // dhcpResults->setInterfaceName(ifname)
-        env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
-
         // set the linkAddress
         // dhcpResults->addLinkAddress(inetAddress, prefixLength)
-        result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
+        result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setIpAddress,
                 env->NewStringUTF(ipaddr), prefixLength);
     }
 
     if (result == 0) {
         // set the gateway
-        // dhcpResults->addGateway(gateway)
         result = env->CallBooleanMethod(dhcpResults,
-                dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
+                dhcpResultsFieldIds.setGateway, env->NewStringUTF(gateway));
     }
 
     if (result == 0) {
@@ -279,12 +273,10 @@
     LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
     dhcpResultsFieldIds.clear =
             env->GetMethodID(dhcpResultsClass, "clear", "()V");
-    dhcpResultsFieldIds.setInterfaceName =
-            env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
-    dhcpResultsFieldIds.addLinkAddress =
-            env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
-    dhcpResultsFieldIds.addGateway =
-            env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
+    dhcpResultsFieldIds.setIpAddress =
+            env->GetMethodID(dhcpResultsClass, "setIpAddress", "(Ljava/lang/String;I)Z");
+    dhcpResultsFieldIds.setGateway =
+            env->GetMethodID(dhcpResultsClass, "setGateway", "(Ljava/lang/String;)Z");
     dhcpResultsFieldIds.addDns =
             env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
     dhcpResultsFieldIds.setDomains =
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png
index 9076900..c31194e 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png
index 3c72bf8..52ed6b2 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png
index d31e113..7b7cde586 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png
index d0c693e..859642a 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png
index dfa19b4..5b71dda 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png
index 151f205..378d82d 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png
index ad3ee2c..43c995a 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png
index 43d66d7..c937837 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png
index 13e4f8b..a60a127 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png
index a09b6b2..db0bf2d 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png
index be02e53..4a6adbe 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png
index 655d387..98983ef 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png
index e870a0a..8e7b62f 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png
index 1d8f805..479a26e 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png
index d348871..77d3130 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png
index 941e91e..cfe684f 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png
index adee78d..4a64a36 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png
index e6b4ca3..29591ff 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png
index 6c2bc0d..cf7cf49 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png
index 763833c..2a2a9af 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png
index 9a87fbc..1f7fe5f 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png
index 6ccf70b..f5d7093 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png
index d1c14a5..3878386 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png
index c2290f0..adcb9e9 100644
--- a/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-hdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png
index 0238898..36ed954 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png
index ada1be9..863eee1 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png
index 82aec64..63e93a8 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png
index 1c6ea9f..85c851d 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png
index ac11400..8637636 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png
index 2025972..2945c29 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png
index 7420fd8..678a6c8 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png
index 1f40832..238a6f1 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png
index cf58e44..4a342a6 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png
index 930a280..5842b19 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png
index ed9bc37..3e1bd2d 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png
index cddb5b0..73ed10b 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png
index bc1f979..03d3dfb 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png
index e6fdbcc..25085cea 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png
index 3d60b43..9e4d2f3 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png
index b9afdc2..ab5bd1e 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png
index c3c8bf2..f5297ce 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png
index 1c7e5e1..1ad56e9 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png
index 6329b73..4bad055 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png
index 424202c..d908034 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png
index 313beca..8ed4fb4 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png
index f18d86a..61d3ced 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png
index 8ab48c0..dec2a82 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png
index fbc2c16..6635830 100644
--- a/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-mdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png
index 265aeb7..df73ef7 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png
index 2f036ad..baf52ed 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png
index bb26440..c8f3b1c 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png
index 1b70047..fe715cf 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png
index b544b98..8e66e11 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png
index c461f3d..537496e 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png
index f57da14..2722a98 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png
index 22c6fbc..81fad09 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png
index cd21ac9..cda20c8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png
index a38dc87..a61ad4b 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png
index d84a342..d6e8e4c 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png
index b82a2eb..785168e 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png
index 6a33ebf..8a648b8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png
index dafc250..03063d4 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png
index 27df6ff..6159dec 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png
index cb4121c..6f1c96c 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png
index c5cbb75..2eaff46 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png
index c69ef41..c4d9db8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png
index aff03d1..f276f16 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png
index fb56ae6..cf9133e 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png
index 88b9d28..8f1a6a8 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png
index 8451958..5080c46 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png
index 6f57654..5e39408 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png
index 21bfc28..435ce21 100644
--- a/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-xhdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png
index c30cb5a..1eca9a9 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png
index eaba558..5427211 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png
index 17c18c9..43c06ab 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png
index 0fce07a..6db3f1e 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png
index c29b837..53b3a62 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png
index ae56a41..7add520 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png
index 85290ac..a4d57de 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png
index 1e8513b..4b3a023 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png
index 8810a12..a4caa65 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png
index 717207f..2ab46c0 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png
index db046f3..5c06e44 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png
index c5c07a4..60d8c11 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png
index c9bdf1f..b149e47 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png
index 6bfd943..6a12a1f 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png
index a1d3fbb..2803c7c 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png
index 40c3a5b..032f6ea 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png
index 26b8736..ea83c35 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png
index 88c027e..2801f29 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png
index 02567c6..66b89b3 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png
index 037d3bf..1f8770c 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png
index 0252769..0d6a95b 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png
index 3ae501d..8e602db 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png
index ecf2831..3143c1f 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png
index 0877749..00fb83e 100644
--- a/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxhdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png
index bc21279..786f493 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png
index b57b592..c6e1ac1f 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png
index 0fb9277..2a65baa 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png
index 340722d..efce521 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png
index 8554a76..5566524 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png
index a05e335..ee676a6 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png
index a5ded14..e0bb175 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png
index 0300a49..de9eadae 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png
index 37dd7ce..3c59ad8 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png
index 6bc549a..d524098 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png
index b026d5d..7c08d71 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png
index 89238dc..017c2e1 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_off_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png
index 1d309fe..d3f2a9a 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00001.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png
index 2e58fa9..cb75295a 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00002.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png
index 2ebe7a7..445644e 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00003.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png
index 04bab76..5819f90 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00004.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png
index 3497e48..91cb90f 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00005.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png
index 42333b4..cf6147c 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00006.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png
index 732e175..75fca7c 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00007.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png
index 12eddd8..b71a0b4 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00008.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png
index 95cbc61..edb7671 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00009.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png
index 105ec07..5e0be17 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00010.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png
index fac253a..b727eda 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00011.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png
index 1b8d11c..a3caefb 100644
--- a/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png
+++ b/core/res/res/drawable-xxxhdpi/btn_switch_to_on_mtrl_00012.9.png
Binary files differ
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index c3f9c76..5f9066a 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -31,9 +31,9 @@
             android:layout_height="wrap_content"
             android:orientation="horizontal"
             android:gravity="center_vertical|start"
-            android:paddingStart="16dip"
-            android:paddingEnd="16dip"
-            android:paddingTop="16dip"
+            android:paddingStart="@dimen/alert_dialog_padding_material"
+            android:paddingEnd="@dimen/alert_dialog_padding_material"
+            android:paddingTop="@dimen/alert_dialog_padding_material"
             android:paddingBottom="8dip">
             <ImageView android:id="@+id/icon"
                 android:layout_width="32dip"
@@ -66,10 +66,10 @@
                 style="?attr/textAppearanceMedium"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:paddingStart="16dip"
-                android:paddingEnd="16dip"
-                android:paddingTop="16dip"
-                android:paddingBottom="16dip" />
+                android:paddingStart="@dimen/alert_dialog_padding_material"
+                android:paddingEnd="@dimen/alert_dialog_padding_material"
+                android:paddingTop="@dimen/alert_dialog_padding_material"
+                android:paddingBottom="@dimen/alert_dialog_padding_material" />
         </ScrollView>
     </LinearLayout>
 
@@ -87,35 +87,33 @@
         style="?attr/buttonBarStyle"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:gravity="end">
-        <LinearLayout
-            android:layout_width="match_parent"
+        android:layoutDirection="locale"
+        android:orientation="horizontal"
+        android:paddingStart="6dp"
+        android:paddingEnd="6dp"
+        android:paddingBottom="6dp">
+        <Button android:id="@+id/button3"
+            style="?attr/buttonBarNeutralButtonStyle"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layoutDirection="locale">
-            <Button android:id="@+id/button3"
-                style="?attr/buttonBarNeutralButtonStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:minHeight="@dimen/alert_dialog_button_bar_height" />
-            <Space
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                android:layout_weight="1"
-                android:visibility="invisible" />
-            <Button android:id="@+id/button2"
-                style="?attr/buttonBarNegativeButtonStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:minHeight="@dimen/alert_dialog_button_bar_height" />
-            <Button android:id="@+id/button1"
-                style="?attr/buttonBarPositiveButtonStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:minHeight="@dimen/alert_dialog_button_bar_height" />
-        </LinearLayout>
-     </LinearLayout>
+            android:maxLines="2"
+            android:minHeight="@dimen/alert_dialog_button_bar_height" />
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:visibility="invisible" />
+        <Button android:id="@+id/button2"
+            style="?attr/buttonBarNegativeButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxLines="2"
+            android:minHeight="@dimen/alert_dialog_button_bar_height" />
+        <Button android:id="@+id/button1"
+            style="?attr/buttonBarPositiveButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxLines="2"
+            android:minHeight="@dimen/alert_dialog_button_bar_height" />
+    </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index e5a3c17..972ae5e 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -42,6 +42,8 @@
     <dimen name="text_size_headline_material">24sp</dimen>
     <dimen name="text_size_title_material">20sp</dimen>
     <dimen name="text_size_subhead_material">16sp</dimen>
+    <dimen name="text_size_title_material_toolbar">20dp</dimen>
+    <dimen name="text_size_subtitle_material_toolbar">16dp</dimen>
     <dimen name="text_size_menu_material">16sp</dimen>
     <dimen name="text_size_body_2_material">14sp</dimen>
     <dimen name="text_size_body_1_material">14sp</dimen>
@@ -71,4 +73,6 @@
 
     <!-- Default alpha value for disabled elements. -->
     <item name="disabled_alpha_material" format="float" type="dimen">0.26</item>
+
+    <dimen name="alert_dialog_padding_material">12dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 27c8207..7ade51d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2530,6 +2530,9 @@
   <public type="style" name="Widget.Material.Spinner.Form" />
   <public type="style" name="Widget.Material.Light.Spinner.Form" />
 
+  <public type="style" name="TextAppearance.Material.Widget.Toolbar.Title" />
+  <public type="style" name="TextAppearance.Material.Widget.Toolbar.Subtitle" />
+
   <public-padding type="string" name="l_resource_pad" end="0x01040030" />
 
   <public type="string" name="config_webSettingsDefaultTextEncoding" />
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 298fea3..c8ea699 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -313,15 +313,38 @@
     </style>
 
     <style name="TextAppearance.Material.Widget.ActionMode"/>
-    <style name="TextAppearance.Material.Widget.ActionMode.Title" parent="TextAppearance.Material.Title" />
-    <style name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Material.Title.Inverse" />
-    <style name="TextAppearance.Material.Widget.ActionMode.Subtitle" parent="TextAppearance.Material.Subhead" />
-    <style name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Material.Subhead.Inverse" />
-
-    <style name="TextAppearance.Material.Widget.ActionBar.Title" parent="TextAppearance.Material.Title" />
-    <style name="TextAppearance.Material.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Material.Title.Inverse" />
-    <style name="TextAppearance.Material.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Subhead" />
-    <style name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Material.Subhead.Inverse" />
+    <style name="TextAppearance.Material.Widget.ActionMode.Title"
+           parent="TextAppearance.Material.Title">
+        <item name="textSize">@dimen/text_size_title_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionMode.Title.Inverse"
+           parent="TextAppearance.Material.Title.Inverse">
+        <item name="textSize">@dimen/text_size_title_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionMode.Subtitle"
+           parent="TextAppearance.Material.Subhead">
+        <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse"
+           parent="TextAppearance.Material.Subhead.Inverse">
+        <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionBar.Title"
+           parent="TextAppearance.Material.Title">
+        <item name="textSize">@dimen/text_size_title_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionBar.Title.Inverse"
+           parent="TextAppearance.Material.Title.Inverse">
+        <item name="textSize">@dimen/text_size_title_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionBar.Subtitle"
+           parent="TextAppearance.Material.Subhead">
+        <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item>
+    </style>
+    <style name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse"
+           parent="TextAppearance.Material.Subhead.Inverse">
+        <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item>
+    </style>
 
     <style name="TextAppearance.Material.Widget.ActionBar.Menu" parent="TextAppearance.Material.Menu">
         <item name="textColor">?attr/actionMenuTextColor</item>
@@ -333,6 +356,11 @@
         <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
     </style>
 
+    <style name="TextAppearance.Material.Widget.Toolbar.Title"
+           parent="TextAppearance.Material.Widget.ActionBar.Title" />
+    <style name="TextAppearance.Material.Widget.Toolbar.Subtitle"
+           parent="TextAppearance.Material.Widget.ActionBar.Subtitle" />
+
     <style name="TextAppearance.Material.WindowTitle" parent="TextAppearance.Material.Title" />
     <style name="TextAppearance.Material.DialogWindowTitle" parent="TextAppearance.Material.Title" />
 
@@ -423,12 +451,15 @@
     <style name="Widget.Material" parent="Widget" />
 
     <!-- Bordered ink button -->
-    <style name="Widget.Material.Button" parent="Widget.Button">
+    <style name="Widget.Material.Button">
         <item name="background">@drawable/btn_default_material</item>
         <item name="textAppearance">?attr/textAppearanceButton</item>
         <item name="minHeight">48dip</item>
         <item name="minWidth">88dip</item>
         <item name="stateListAnimator">@anim/button_state_list_anim_material</item>
+        <item name="focusable">true</item>
+        <item name="clickable">true</item>
+        <item name="gravity">center_vertical|center_horizontal</item>
     </style>
 
     <!-- Small bordered ink button -->
@@ -471,9 +502,6 @@
 
     <style name="Widget.Material.ButtonBar.AlertDialog">
         <item name="background">@null</item>
-        <item name="paddingStart">16dp</item>
-        <item name="paddingEnd">16dp</item>
-        <item name="paddingBottom">16dp</item>
         <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
     </style>
 
@@ -759,6 +787,8 @@
 
     <style name="Widget.Material.Toolbar" parent="Widget.Toolbar">
         <item name="navigationButtonStyle">@style/Widget.Material.Toolbar.Button.Navigation</item>
+        <item name="titleTextAppearance">@style/TextAppearance.Material.Widget.Toolbar.Title</item>
+        <item name="subtitleTextAppearance">@style/TextAppearance.Material.Widget.Toolbar.Subtitle</item>
     </style>
 
     <style name="Widget.Material.Toolbar.Button.Navigation" parent="Widget.Toolbar.Button.Navigation">
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index 116a31e..93b16e7 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -26,8 +26,8 @@
 import android.net.IpConfiguration.IpAssignment;
 import android.net.IpConfiguration.ProxySettings;
 import android.net.LinkAddress;
-import android.net.LinkProperties;
 import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -116,7 +116,7 @@
         boolean usercert = false;
         WifiConfiguration config = null;
         int securityType = NONE;
-        LinkProperties mLinkProperties = null;
+        StaticIpConfiguration mStaticIpConfiguration = null;
         InetAddress mInetAddr = null;
 
         @Override
@@ -153,7 +153,7 @@
                 usercert = true;
             }
             if (tagName.equalsIgnoreCase("ip")) {
-                mLinkProperties = new LinkProperties();
+                mStaticIpConfiguration = new StaticIpConfiguration();
                 ip = true;
             }
             if (tagName.equalsIgnoreCase("gateway")) {
@@ -173,15 +173,15 @@
         @Override
         public void endElement(String uri, String localName, String tagName) throws SAXException {
             if (tagName.equalsIgnoreCase("accesspoint")) {
-                if (mLinkProperties != null) {
+                if (mStaticIpConfiguration != null) {
                     config.setIpAssignment(IpAssignment.STATIC);
-                    config.setLinkProperties(mLinkProperties);
+                    config.setStaticIpConfiguration(mStaticIpConfiguration);
                 } else {
                     config.setIpAssignment(IpAssignment.DHCP);
                 }
                 config.setProxySettings(ProxySettings.NONE);
                 networks.add(config);
-                mLinkProperties = null;
+                mStaticIpConfiguration = null;
             }
         }
 
@@ -312,7 +312,7 @@
                     if (!InetAddress.isNumeric(gwAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr)));
+                    mStaticIpConfiguration.gateway = InetAddress.getByName(gwAddr);
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
@@ -324,7 +324,7 @@
                     if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength));
+                    mStaticIpConfiguration.ipAddress = new LinkAddress(mInetAddr, nwPrefixLength);
                 } catch (NumberFormatException e) {
                     throw new SAXException();
                 }
@@ -336,7 +336,7 @@
                     if (!InetAddress.isNumeric(dnsAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
+                    mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(dnsAddr));
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
@@ -348,7 +348,7 @@
                     if (!InetAddress.isNumeric(dnsAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
+                    mStaticIpConfiguration.dnsServers.add(InetAddress.getByName(dnsAddr));
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 3177023..4bf0b71 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -18,15 +18,15 @@
 
 import android.annotation.NonNull;
 import android.graphics.drawable.Drawable;
-import android.view.View;
 
 /**
  * Defines a simple shape, used for bounding graphical regions.
  * <p>
- * Can be used with a View, or computed by a Drawable, to drive the shape of shadows cast by a
- * View, or to clip the contents of the View.
+ * Can be computed for a View, or computed by a Drawable, to drive the shape of
+ * shadows cast by a View, or to clip the contents of the View.
  *
- * @see View#setOutline(Outline)
+ * @see android.view.ViewOutlineProvider
+ * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider)
  * @see Drawable#getOutline(Outline)
  */
 public final class Outline {
@@ -79,21 +79,27 @@
 
     /**
      * Returns whether the outline can be used to clip a View.
+     * <p>
+     * Currently, only Outlines that can be represented as a rectangle, circle,
+     * or round rect support clipping.
      *
-     * Currently, only outlines that can be represented as a rectangle, circle, or round rect
-     * support clipping.
-     *
-     * @see {@link View#setClipToOutline(boolean)}
+     * @see {@link android.view.View#setClipToOutline(boolean)}
      */
     public boolean canClip() {
         return !isEmpty() && mRect != null;
     }
 
     /**
-     * Sets the alpha represented by the Outline.
-     *
-     * Content producing a fully opaque (alpha = 1.0f) outline is assumed by the drawing system
-     * to fully cover content beneath it, meaning content beneath may be optimized away.
+     * Sets the alpha represented by the Outline - the degree to which the
+     * producer is guaranteed to be opaque over the Outline's shape.
+     * <p>
+     * An alpha value of <code>0.0f</code> either represents completely
+     * transparent content, or content that isn't guaranteed to fill the shape
+     * it publishes.
+     * <p>
+     * Content producing a fully opaque (alpha = <code>1.0f</code>) outline is
+     * assumed by the drawing system to fully cover content beneath it,
+     * meaning content beneath may be optimized away.
      */
     public void setAlpha(float alpha) {
         mAlpha = alpha;
@@ -130,7 +136,8 @@
     }
 
     /**
-     * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
+     * Sets the Outline to the rounded rect defined by the input rect, and
+     * corner radius.
      */
     public void setRect(int left, int top, int right, int bottom) {
         setRoundRect(left, top, right, bottom, 0.0f);
@@ -145,7 +152,7 @@
 
     /**
      * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
-     *
+     * <p>
      * Passing a zero radius is equivalent to calling {@link #setRect(int, int, int, int)}
      */
     public void setRoundRect(int left, int top, int right, int bottom, float radius) {
@@ -196,7 +203,8 @@
     }
 
     /**
-     * Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}.
+     * Sets the Constructs an Outline from a
+     * {@link android.graphics.Path#isConvex() convex path}.
      */
     public void setConvexPath(@NonNull Path convexPath) {
         if (convexPath.isEmpty()) {
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 1c76d9c..652fe64 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1109,9 +1109,16 @@
      * This draws a shadow layer below the main layer, with the specified
      * offset and color, and blur radius. If radius is 0, then the shadow
      * layer is removed.
+     * <p>
+     * Can be used to create a blurred shadow underneath text. Support for use
+     * with other drawing operations is constrained to the software rendering
+     * pipeline.
+     * <p>
+     * The alpha of the shadow will be the paint's alpha if the shadow color is
+     * opaque, or the alpha from the shadow color if not.
      */
-    public void setShadowLayer(float radius, float dx, float dy, int color) {
-      native_setShadowLayer(mNativePaint, radius, dx, dy, color);
+    public void setShadowLayer(float radius, float dx, float dy, int shadowColor) {
+      native_setShadowLayer(mNativePaint, radius, dx, dy, shadowColor);
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index a383aab..29b9141 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -820,7 +820,7 @@
 
     @Override
     public int getOpacity() {
-        return (mAlpha == 255 && mGradientState.mOpaque) ?
+        return (mAlpha == 255 && mGradientState.mOpaqueOverBounds) ?
                 PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
     }
 
@@ -1413,7 +1413,8 @@
     public void getOutline(Outline outline) {
         final GradientState st = mGradientState;
         final Rect bounds = getBounds();
-        outline.setAlpha(mAlpha / 255.0f);
+        // only report non-zero alpha if shape being drawn is opaque
+        outline.setAlpha(st.mOpaqueOverShape ? (mAlpha / 255.0f) : 0.0f);
 
         switch (st.mShape) {
             case RECTANGLE:
@@ -1492,7 +1493,8 @@
         private int mGradientRadiusType = RADIUS_TYPE_PIXELS;
         private boolean mUseLevel;
         private boolean mUseLevelForShape;
-        private boolean mOpaque;
+        private boolean mOpaqueOverBounds;
+        private boolean mOpaqueOverShape;
 
         int[] mThemeAttrs;
         int[] mAttrSize;
@@ -1544,7 +1546,7 @@
             mGradientRadiusType = state.mGradientRadiusType;
             mUseLevel = state.mUseLevel;
             mUseLevelForShape = state.mUseLevelForShape;
-            mOpaque = state.mOpaque;
+            mOpaqueOverBounds = state.mOpaqueOverBounds;
             mThemeAttrs = state.mThemeAttrs;
             mAttrSize = state.mAttrSize;
             mAttrGradient = state.mAttrGradient;
@@ -1606,40 +1608,36 @@
         }
 
         private void computeOpacity() {
-            if (mShape != RECTANGLE) {
-                mOpaque = false;
-                return;
-            }
+            mOpaqueOverBounds = false;
+            mOpaqueOverShape = false;
 
-            if (mRadius > 0 || mRadiusArray != null) {
-                mOpaque = false;
-                return;
-            }
-
+            // First test opacity of all colors
             if (mStrokeWidth > 0) {
                 if (mStrokeColorStateList != null) {
                     if (!mStrokeColorStateList.isOpaque()) {
-                        mOpaque = false;
                         return;
                     }
                 }
             }
 
             if (mColorStateList != null && !mColorStateList.isOpaque()) {
-                mOpaque = false;
                 return;
             }
 
             if (mColors != null) {
                 for (int i = 0; i < mColors.length; i++) {
                     if (!isOpaque(mColors[i])) {
-                        mOpaque = false;
                         return;
                     }
                 }
             }
 
-            mOpaque = true;
+            // Colors are opaque, so opaqueOverShape=true,
+            mOpaqueOverShape = true;
+            // and opaqueOverBounds=true if shape fills bounds
+            mOpaqueOverBounds = mShape == RECTANGLE
+                    && mRadius <= 0
+                    && mRadiusArray == null;
         }
 
         private static boolean isOpaque(int color) {
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 0aa1b0d..c185a9e 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -446,19 +446,8 @@
                         ": <nine-patch> requires a valid 9-patch source image");
             }
 
-            // Hey, now might be a good time to actually load optical bounds!
             bitmap.getOpticalInsets(opticalInsets);
 
-            // Sanity check for valid padding when we have optical insets.
-            if (padding.left < opticalInsets.left) {
-                padding.left = opticalInsets.left;
-                padding.right = opticalInsets.right;
-            }
-            if (padding.top < opticalInsets.top) {
-                padding.top = opticalInsets.top;
-                padding.bottom = opticalInsets.bottom;
-            }
-
             state.mNinePatch = new NinePatch(bitmap, bitmap.getNinePatchChunk());
             state.mPadding = padding;
             state.mOpticalInsets = Insets.of(opticalInsets);
@@ -626,21 +615,6 @@
             mOpticalInsets = Insets.of(opticalInsets);
             mDither = dither;
             mAutoMirrored = autoMirror;
-
-            // Sanity check for valid padding when we have optical insets.
-            if (opticalInsets != null && !opticalInsets.isEmpty()) {
-                if (mPadding == null) {
-                    mPadding = new Rect();
-                }
-                if (mPadding.left < opticalInsets.left) {
-                    mPadding.left = opticalInsets.left;
-                    mPadding.right = opticalInsets.right;
-                }
-                if (mPadding.top < opticalInsets.top) {
-                    mPadding.top = opticalInsets.top;
-                    mPadding.bottom = opticalInsets.bottom;
-                }
-            }
         }
 
         // Copy constructor
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index c6d3db7..5f533a7 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -208,6 +208,8 @@
         // ensure that local bounds cover mapped bounds
         if (!state.mMatrix.isSimple()) return false;
 
+        if (state.mRoundRectClipState) return false;
+
         // check state/paint for transparency
         if (mPaint) {
             if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) {
@@ -999,6 +1001,8 @@
 public:
     DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint) {};
+    DrawStrokableOp(const Rect& localBounds, const SkPaint* paint)
+            : DrawBoundedOp(localBounds, paint) {};
 
     virtual bool getLocalBounds(Rect& localBounds) {
         localBounds.set(mLocalBounds);
@@ -1337,11 +1341,11 @@
     const float* mPositions;
 };
 
-class DrawTextOp : public DrawBoundedOp {
+class DrawTextOp : public DrawStrokableOp {
 public:
     DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
             const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds)
-            : DrawBoundedOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
+            : DrawStrokableOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
             mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) {
         mPrecacheTransform = SkMatrix::InvalidMatrix();
     }
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 94162fc..9a9c544 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -376,7 +376,7 @@
         float x, float y, const float* positions, const SkPaint* paint,
         float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
 
-    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
+    if (!text || count <= 0 || paintWillNotDrawText(*paint)) return DrawGlInfo::kStatusDone;
 
     text = refText(text, bytesCount);
     positions = refBuffer<float>(positions, count * 2);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 721ab3d..bbf0551 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2518,8 +2518,9 @@
 
 status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, const SkPaint* p) {
-    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
-            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
+    if (currentSnapshot()->isIgnored()
+            || quickRejectSetupScissor(left, top, right, bottom, p)
+            || paintWillNotDraw(*p)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2536,9 +2537,9 @@
 }
 
 status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
-    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(x - radius, y - radius,
-            x + radius, y + radius, p) ||
-            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
+    if (currentSnapshot()->isIgnored()
+            || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p)
+            || paintWillNotDraw(*p)) {
         return DrawGlInfo::kStatusDone;
     }
     if (p->getPathEffect() != 0) {
@@ -2558,8 +2559,9 @@
 
 status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
         const SkPaint* p) {
-    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
-            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
+    if (currentSnapshot()->isIgnored()
+            || quickRejectSetupScissor(left, top, right, bottom, p)
+            || paintWillNotDraw(*p)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2580,8 +2582,9 @@
 
 status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) {
-    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
-            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
+    if (currentSnapshot()->isIgnored()
+            || quickRejectSetupScissor(left, top, right, bottom, p)
+            || paintWillNotDraw(*p)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2614,8 +2617,9 @@
 
 status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
         const SkPaint* p) {
-    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
-            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
+    if (currentSnapshot()->isIgnored()
+            || quickRejectSetupScissor(left, top, right, bottom, p)
+            || paintWillNotDraw(*p)) {
         return DrawGlInfo::kStatusDone;
     }
 
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index f5cd266..6d4bb4a 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -67,6 +67,18 @@
         return resultMode;
     }
 
+    // TODO: move to a method on android:Paint
+    static inline bool paintWillNotDraw(const SkPaint& paint) {
+        return paint.getAlpha() == 0
+                && getXfermode(paint.getXfermode()) != SkXfermode::kClear_Mode;
+    }
+
+    // TODO: move to a method on android:Paint
+    static inline bool paintWillNotDrawText(const SkPaint& paint) {
+        return paint.getAlpha() == 0
+                && paint.getLooper() == NULL
+                && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
+    }
 // ----------------------------------------------------------------------------
 // Frame state operations
 // ----------------------------------------------------------------------------
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6a76a71..e69c456 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2332,18 +2332,21 @@
     }
 
     /**
-     * Registers a {@link RemoteController} instance for it to receive media metadata updates
-     * and playback state information from applications using {@link RemoteControlClient}, and
-     * control their playback.
-     * <p>Registration requires the {@link OnClientUpdateListener} listener to be one of the
-     * enabled notification listeners (see
+     * Registers a {@link RemoteController} instance for it to receive media
+     * metadata updates and playback state information from applications using
+     * {@link RemoteControlClient}, and control their playback.
+     * <p>
+     * Registration requires the {@link OnClientUpdateListener} listener to be
+     * one of the enabled notification listeners (see
      * {@link android.service.notification.NotificationListenerService}).
+     *
      * @param rctlr the object to register.
-     * @return true if the {@link RemoteController} was successfully registered, false if an
-     *     error occurred, due to an internal system error, or insufficient permissions.
+     * @return true if the {@link RemoteController} was successfully registered,
+     *         false if an error occurred, due to an internal system error, or
+     *         insufficient permissions.
      * @deprecated Use
-     * {@link MediaSessionManager#addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, ComponentName)}
-     * and {@link MediaController} instead.
+     *             {@link MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, ComponentName)}
+     *             and {@link MediaController} instead.
      */
     @Deprecated
     public boolean registerRemoteController(RemoteController rctlr) {
@@ -2355,12 +2358,14 @@
     }
 
     /**
-     * Unregisters a {@link RemoteController}, causing it to no longer receive media metadata and
-     * playback state information, and no longer be capable of controlling playback.
+     * Unregisters a {@link RemoteController}, causing it to no longer receive
+     * media metadata and playback state information, and no longer be capable
+     * of controlling playback.
+     *
      * @param rctlr the object to unregister.
      * @deprecated Use
-     * {@link MediaSessionManager#removeActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener)}
-     * instead.
+     *             {@link MediaSessionManager#removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener)}
+     *             instead.
      */
     @Deprecated
     public void unregisterRemoteController(RemoteController rctlr) {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 2fa0c93..7c3b4fc 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1049,8 +1049,17 @@
     private void setDataSource(String path, String[] keys, String[] values)
             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
         final Uri uri = Uri.parse(path);
-        if ("file".equals(uri.getScheme())) {
+        final String scheme = uri.getScheme();
+        if ("file".equals(scheme)) {
             path = uri.getPath();
+        } else if (scheme != null) {
+            // handle non-file sources
+            nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                keys,
+                values);
+            return;
         }
 
         final File file = new File(path);
@@ -1060,20 +1069,10 @@
             setDataSource(fd);
             is.close();
         } else {
-            _setDataSource(path, keys, values);
+            throw new IOException("setDataSource failed.");
         }
     }
 
-    private void _setDataSource(
-        String path, String[] keys, String[] values)
-        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
-        nativeSetDataSource(
-                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
-                path,
-                keys,
-                values);
-    }
-
     private native void nativeSetDataSource(
         IBinder httpServiceBinder, String path, String[] keys, String[] values)
         throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index adc8391..f378cef 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -74,7 +74,7 @@
     private MetadataEditor mMetadataEditor;
 
     private MediaSessionManager mSessionManager;
-    private MediaSessionManager.SessionListener mSessionListener;
+    private MediaSessionManager.OnActiveSessionsChangedListener mSessionListener;
     private MediaController.Callback mSessionCb = new MediaControllerCallback();
 
     /**
@@ -140,7 +140,7 @@
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         mSessionManager = (MediaSessionManager) context
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
-        mSessionListener = new TopTransportSessionListener(context);
+        mSessionListener = new TopTransportSessionListener();
 
         if (ActivityManager.isLowRamDeviceStatic()) {
             mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
@@ -710,11 +710,8 @@
      * Listens for changes to the active session stack and replaces the
      * currently tracked session if it has changed.
      */
-    private class TopTransportSessionListener extends MediaSessionManager.SessionListener {
-
-        public TopTransportSessionListener(Context context) {
-            super(context);
-        }
+    private class TopTransportSessionListener implements
+            MediaSessionManager.OnActiveSessionsChangedListener {
 
         @Override
         public void onActiveSessionsChanged(List<MediaController> controllers) {
@@ -792,7 +789,7 @@
     void startListeningToSessions() {
         final ComponentName listenerComponent = new ComponentName(mContext,
                 mOnClientUpdateListener.getClass());
-        mSessionManager.addActiveSessionsListener(mSessionListener, listenerComponent,
+        mSessionManager.addOnActiveSessionsChangedListener(mSessionListener, listenerComponent,
                 UserHandle.myUserId(), null);
         mSessionListener.onActiveSessionsChanged(mSessionManager
                 .getActiveSessions(listenerComponent));
@@ -806,7 +803,7 @@
      * @hide
      */
     void stopListeningToSessions() {
-        mSessionManager.removeActiveSessionsListener(mSessionListener);
+        mSessionManager.removeOnActiveSessionsChangedListener(mSessionListener);
         if (DEBUG) {
             Log.d(TAG, "Unregistered session listener for user "
                     + UserHandle.myUserId());
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 63c85f8..074e5ad 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -185,7 +185,7 @@
      *
      * @return The current play queue or null.
      */
-    public @Nullable List<MediaSession.Track> getQueue() {
+    public @Nullable List<MediaSession.Item> getQueue() {
         try {
             ParceledListSlice queue = mSessionBinder.getQueue();
             if (queue != null) {
@@ -259,18 +259,18 @@
     }
 
     /**
-     * Get the current volume info for this session.
+     * Get the current audio info for this session.
      *
-     * @return The current volume info or null.
+     * @return The current audio info or null.
      */
-    public @Nullable VolumeInfo getVolumeInfo() {
+    public @Nullable AudioInfo getAudioInfo() {
         try {
             ParcelableVolumeInfo result = mSessionBinder.getVolumeAttributes();
-            return new VolumeInfo(result.volumeType, result.audioAttrs, result.controlType,
+            return new AudioInfo(result.volumeType, result.audioAttrs, result.controlType,
                     result.maxVolume, result.currentVolume);
 
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getVolumeInfo.", e);
+            Log.wtf(TAG, "Error calling getAudioInfo.", e);
         }
         return null;
     }
@@ -305,7 +305,7 @@
      * {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
      * {@link AudioManager} may be used to affect the handling.
      *
-     * @see #getVolumeInfo()
+     * @see #getAudioInfo()
      * @param value The value to set it to, between 0 and the reported max.
      * @param flags Any flags to pass with the command.
      */
@@ -326,7 +326,7 @@
      * {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
      * {@link AudioManager} may be used to affect the handling.
      *
-     * @see #getVolumeInfo()
+     * @see #getAudioInfo()
      * @param direction The direction to adjust the volume in.
      * @param flags Any flags to pass with the command.
      */
@@ -544,13 +544,14 @@
         }
 
         /**
-         * Override to handle changes to tracks in the queue.
+         * Override to handle changes to items in the queue.
          *
-         * @param queue A list of tracks in the current play queue. It should include the currently
-         *              playing track as well as previous and upcoming tracks if applicable.
-         * @see MediaSession.Track
+         * @param queue A list of items in the current play queue. It should
+         *            include the currently playing item as well as previous and
+         *            upcoming items if applicable.
+         * @see MediaSession.Item
          */
-        public void onQueueChanged(@Nullable List<MediaSession.Track> queue) {
+        public void onQueueChanged(@Nullable List<MediaSession.Item> queue) {
         }
 
         /**
@@ -572,11 +573,11 @@
         }
 
         /**
-         * Override to handle changes to the volume info.
+         * Override to handle changes to the audio info.
          *
-         * @param info The current volume info for this session.
+         * @param info The current audio info for this session.
          */
-        public void onVolumeInfoChanged(VolumeInfo info) {
+        public void onAudioInfoChanged(AudioInfo info) {
         }
     }
 
@@ -638,14 +639,14 @@
         }
 
         /**
-         * Play a track with a specific id in the play queue.
-         * If you specify an id that is not in the play queue, the behavior is undefined.
+         * Play an item with a specific id in the play queue. If you specify an
+         * id that is not in the play queue, the behavior is undefined.
          */
-        public void skipToTrack(long id) {
+        public void skipToItem(long id) {
             try {
                 mSessionBinder.skipToTrack(id);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling skipToTrack(" + id + ").", e);
+                Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
             }
         }
 
@@ -784,9 +785,9 @@
     }
 
     /**
-     * Holds information about the way volume is handled for this session.
+     * Holds information about the way audio is handled for this session.
      */
-    public static final class VolumeInfo {
+    public static final class AudioInfo {
         private final int mVolumeType;
         private final int mVolumeControl;
         private final int mMaxVolume;
@@ -796,7 +797,7 @@
         /**
          * @hide
          */
-        public VolumeInfo(int type, AudioAttributes attrs, int control, int max, int current) {
+        public AudioInfo(int type, AudioAttributes attrs, int control, int max, int current) {
             mVolumeType = type;
             mAudioAttrs = attrs;
             mVolumeControl = control;
@@ -904,7 +905,7 @@
 
         @Override
         public void onQueueChanged(ParceledListSlice parceledQueue) {
-            List<MediaSession.Track> queue = parceledQueue.getList();
+            List<MediaSession.Item> queue = parceledQueue.getList();
             MediaController controller = mController.get();
             if (controller != null) {
                 controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
@@ -931,7 +932,7 @@
         public void onVolumeInfoChanged(ParcelableVolumeInfo pvi) {
             MediaController controller = mController.get();
             if (controller != null) {
-                VolumeInfo info = new VolumeInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
+                AudioInfo info = new AudioInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
                         pvi.maxVolume, pvi.currentVolume);
                 controller.postMessage(MSG_UPDATE_VOLUME, info, null);
             }
@@ -960,7 +961,7 @@
                     mCallback.onMetadataChanged((MediaMetadata) msg.obj);
                     break;
                 case MSG_UPDATE_QUEUE:
-                    mCallback.onQueueChanged((List<MediaSession.Track>) msg.obj);
+                    mCallback.onQueueChanged((List<MediaSession.Item>) msg.obj);
                     break;
                 case MSG_UPDATE_QUEUE_TITLE:
                     mCallback.onQueueTitleChanged((CharSequence) msg.obj);
@@ -969,7 +970,7 @@
                     mCallback.onExtrasChanged((Bundle) msg.obj);
                     break;
                 case MSG_UPDATE_VOLUME:
-                    mCallback.onVolumeInfoChanged((VolumeInfo) msg.obj);
+                    mCallback.onAudioInfoChanged((AudioInfo) msg.obj);
                     break;
                 case MSG_DESTROYED:
                     mCallback.onSessionDestroyed();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index cf73c2a..2cd161c 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -435,18 +435,19 @@
     }
 
     /**
-     * Update the list of tracks in the play queue. It is an ordered list and should contain the
-     * current track, and previous or upcoming tracks if they exist.
-     * Specify null if there is no current play queue.
+     * Update the list of items in the play queue. It is an ordered list and
+     * should contain the current item, and previous or upcoming items if they
+     * exist. Specify null if there is no current play queue.
      * <p>
-     * The queue should be of reasonable size. If the play queue is unbounded within your
-     * app, it is better to send a reasonable amount in a sliding window instead.
+     * The queue should be of reasonable size. If the play queue is unbounded
+     * within your app, it is better to send a reasonable amount in a sliding
+     * window instead.
      *
-     * @param queue A list of tracks in the play queue.
+     * @param queue A list of items in the play queue.
      */
-    public void setQueue(@Nullable List<Track> queue) {
+    public void setQueue(@Nullable List<Item> queue) {
         try {
-            mBinder.setQueue(new ParceledListSlice<Track>(queue));
+            mBinder.setQueue(new ParceledListSlice<Item>(queue));
         } catch (RemoteException e) {
             Log.wtf("Dead object in setQueue.", e);
         }
@@ -512,8 +513,8 @@
         postToCallback(CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
     }
 
-    private void dispatchSkipToTrack(long id) {
-        postToCallback(CallbackMessageHandler.MSG_SKIP_TO_TRACK, id);
+    private void dispatchSkipToItem(long id) {
+        postToCallback(CallbackMessageHandler.MSG_SKIP_TO_ITEM, id);
     }
 
     private void dispatchPause() {
@@ -782,9 +783,10 @@
         }
 
         /**
-         * Override to handle requests to play a track with a given id from the play queue.
+         * Override to handle requests to play an item with a given id from the
+         * play queue.
          */
-        public void onSkipToTrack(long id) {
+        public void onSkipToItem(long id) {
         }
 
         /**
@@ -916,7 +918,7 @@
         public void onSkipToTrack(long id) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
-                session.dispatchSkipToTrack(id);
+                session.dispatchSkipToItem(id);
             }
         }
 
@@ -1015,12 +1017,12 @@
     }
 
     /**
-     * A single track that is part of the play queue. It contains information necessary to display
-     * a single track in the queue.
+     * A single item that is part of the play queue. It contains information
+     * necessary to display a single item in the queue.
      */
-    public static final class Track implements Parcelable {
+    public static final class Item implements Parcelable {
         /**
-         * This id is reserved. No tracks can be explicitly asigned this id.
+         * This id is reserved. No items can be explicitly asigned this id.
          */
         public static final int UNKNOWN_ID = -1;
 
@@ -1030,22 +1032,23 @@
         private final Bundle mExtras;
 
         /**
-         * Create a new {@link MediaSession.Track}.
+         * Create a new {@link MediaSession.Item}.
          *
-         * @param metadata The metadata for this track.
-         * @param id An identifier for this track. It must be unique within the play queue.
-         * @param uri The uri for this track.
-         * @param extras A bundle of extras that can be used to add extra information about the
-         *               track.
+         * @param metadata The metadata for this item.
+         * @param id An identifier for this item. It must be unique within the
+         *            play queue.
+         * @param uri The uri for this item.
+         * @param extras A bundle of extras that can be used to add extra
+         *            information about this item.
          */
-        private Track(MediaMetadata metadata, long id, Uri uri, Bundle extras) {
+        private Item(MediaMetadata metadata, long id, Uri uri, Bundle extras) {
             mMetadata = metadata;
             mId = id;
             mUri = uri;
             mExtras = extras;
         }
 
-        private Track(Parcel in) {
+        private Item(Parcel in) {
             mMetadata = MediaMetadata.CREATOR.createFromParcel(in);
             mId = in.readLong();
             mUri = Uri.CREATOR.createFromParcel(in);
@@ -1053,35 +1056,35 @@
         }
 
         /**
-         * Get the metadata for this track.
+         * Get the metadata for this item.
          */
         public MediaMetadata getMetadata() {
             return mMetadata;
         }
 
         /**
-         * Get the id for this track.
+         * Get the id for this item.
          */
         public long getId() {
             return mId;
         }
 
         /**
-         * Get the Uri for this track.
+         * Get the Uri for this item.
          */
         public Uri getUri() {
             return mUri;
         }
 
         /**
-         * Get the extras for this track.
+         * Get the extras for this item.
          */
         public Bundle getExtras() {
             return mExtras;
         }
 
         /**
-         * Builder for {@link MediaSession.Track} objects.
+         * Builder for {@link MediaSession.Item} objects.
          */
         public static final class Builder {
             private final MediaMetadata mMetadata;
@@ -1096,15 +1099,15 @@
             public Builder(MediaMetadata metadata, long id, Uri uri) {
                 if (metadata == null) {
                     throw new IllegalArgumentException(
-                            "You must specify a non-null MediaMetadata to build a Track.");
+                            "You must specify a non-null MediaMetadata to build an Item.");
                 }
                 if (uri == null) {
                     throw new IllegalArgumentException(
-                            "You must specify a non-null Uri to build a Track.");
+                            "You must specify a non-null Uri to build an Item.");
                 }
                 if (id == UNKNOWN_ID) {
                     throw new IllegalArgumentException(
-                            "You must specify an id other than UNKNOWN_ID to build a Track.");
+                            "You must specify an id other than UNKNOWN_ID to build an Item.");
                 }
                 mMetadata = metadata;
                 mId = id;
@@ -1112,18 +1115,18 @@
             }
 
             /**
-             * Set optional extras for the track.
+             * Set optional extras for the item.
              */
-            public MediaSession.Track.Builder setExtras(Bundle extras) {
+            public MediaSession.Item.Builder setExtras(Bundle extras) {
                 mExtras = extras;
                 return this;
             }
 
             /**
-             * Create the {@link Track}.
+             * Create the {@link Item}.
              */
-            public MediaSession.Track build() {
-                return new MediaSession.Track(mMetadata, mId, mUri, mExtras);
+            public MediaSession.Item build() {
+                return new MediaSession.Item(mMetadata, mId, mUri, mExtras);
             }
         }
 
@@ -1140,23 +1143,23 @@
             return 0;
         }
 
-        public static final Creator<MediaSession.Track> CREATOR
-                = new Creator<MediaSession.Track>() {
+        public static final Creator<MediaSession.Item> CREATOR
+                = new Creator<MediaSession.Item>() {
 
             @Override
-            public MediaSession.Track createFromParcel(Parcel p) {
-                return new MediaSession.Track(p);
+            public MediaSession.Item createFromParcel(Parcel p) {
+                return new MediaSession.Item(p);
             }
 
             @Override
-            public MediaSession.Track[] newArray(int size) {
-                return new MediaSession.Track[size];
+            public MediaSession.Item[] newArray(int size) {
+                return new MediaSession.Item[size];
             }
         };
 
         @Override
         public String toString() {
-            return "MediaSession.Track {" +
+            return "MediaSession.Item {" +
                     "Metadata=" + mMetadata +
                     ", Id=" + mId +
                     ", Uri=" + mUri +
@@ -1182,7 +1185,7 @@
         private static final int MSG_PLAY = 1;
         private static final int MSG_PLAY_URI = 2;
         private static final int MSG_PLAY_SEARCH = 3;
-        private static final int MSG_SKIP_TO_TRACK = 4;
+        private static final int MSG_SKIP_TO_ITEM = 4;
         private static final int MSG_PAUSE = 5;
         private static final int MSG_STOP = 6;
         private static final int MSG_NEXT = 7;
@@ -1232,8 +1235,8 @@
                 case MSG_PLAY_SEARCH:
                     mCallback.onPlayFromSearch((String) msg.obj, msg.getData());
                     break;
-                case MSG_SKIP_TO_TRACK:
-                    mCallback.onSkipToTrack((Long) msg.obj);
+                case MSG_SKIP_TO_ITEM:
+                    mCallback.onSkipToItem((Long) msg.obj);
                 case MSG_PAUSE:
                     mCallback.onPause();
                     break;
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index c2fb5a3..8a1e076 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -30,6 +30,7 @@
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.KeyEvent;
 
@@ -50,6 +51,9 @@
 public final class MediaSessionManager {
     private static final String TAG = "SessionManager";
 
+    private final ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper> mListeners
+            = new ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper>();
+    private final Object mLock = new Object();
     private final ISessionManager mService;
 
     private Context mContext;
@@ -141,10 +145,11 @@
      * @param notificationListener The enabled notification listener component.
      *            May be null.
      */
-    public void addActiveSessionsListener(@NonNull SessionListener sessionListener,
+    public void addOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener sessionListener,
             @Nullable ComponentName notificationListener) {
-        addActiveSessionsListener(sessionListener, notificationListener, UserHandle.myUserId(),
-                null);
+        addOnActiveSessionsChangedListener(sessionListener, notificationListener,
+                UserHandle.myUserId(), null);
     }
 
     /**
@@ -163,7 +168,8 @@
      * @param handler The handler to post updates on.
      * @hide
      */
-    public void addActiveSessionsListener(@NonNull SessionListener sessionListener,
+    public void addOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener sessionListener,
             @Nullable ComponentName notificationListener, int userId, @Nullable Handler handler) {
         if (sessionListener == null) {
             throw new IllegalArgumentException("listener may not be null");
@@ -171,11 +177,18 @@
         if (handler == null) {
             handler = new Handler();
         }
-        sessionListener.setHandler(handler);
-        try {
-            mService.addSessionsListener(sessionListener.mStub, notificationListener, userId);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in addActiveSessionsListener.", e);
+        synchronized (mLock) {
+            if (mListeners.get(sessionListener) != null) {
+                Log.w(TAG, "Attempted to add session listener twice, ignoring.");
+                return;
+            }
+            SessionsChangedWrapper wrapper = new SessionsChangedWrapper(sessionListener, handler);
+            try {
+                mService.addSessionsListener(wrapper.mStub, notificationListener, userId);
+                mListeners.put(sessionListener, wrapper);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in addOnActiveSessionsChangedListener.", e);
+            }
         }
     }
 
@@ -184,14 +197,20 @@
      *
      * @param listener The listener to remove.
      */
-    public void removeActiveSessionsListener(@NonNull SessionListener listener) {
+    public void removeOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener listener) {
         if (listener == null) {
             throw new IllegalArgumentException("listener may not be null");
         }
-        try {
-            mService.removeSessionsListener(listener.mStub);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in removeActiveSessionsListener.", e);
+        synchronized (mLock) {
+            SessionsChangedWrapper wrapper = mListeners.remove(listener);
+            if (wrapper != null) {
+                try {
+                    mService.removeSessionsListener(wrapper.mStub);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in removeOnActiveSessionsChangedListener.", e);
+                }
+            }
         }
     }
 
@@ -257,28 +276,18 @@
 
     /**
      * Listens for changes to the list of active sessions. This can be added
-     * using {@link #addActiveSessionsListener}.
+     * using {@link #addOnActiveSessionsChangedListener}.
      */
-    public static abstract class SessionListener {
-        private final Context mContext;
-        private Handler mHandler;
+    public interface OnActiveSessionsChangedListener {
+        public void onActiveSessionsChanged(@Nullable List<MediaController> controllers);
+    }
 
-        public SessionListener(Context context) {
-            mContext = context;
-        }
-        /**
-         * Called when the list of active sessions has changed. This can be due
-         * to a session being added or removed or the order of sessions
-         * changing. The controllers will be provided in priority order with the
-         * most important controller at index 0.
-         *
-         * @param controllers The updated list of controllers for the user that
-         *            changed.
-         */
-        public abstract void onActiveSessionsChanged(
-                @Nullable List<MediaController> controllers);
+    private final class SessionsChangedWrapper {
+        private final OnActiveSessionsChangedListener mListener;
+        private final Handler mHandler;
 
-        private final void setHandler(Handler handler) {
+        public SessionsChangedWrapper(OnActiveSessionsChangedListener listener, Handler handler) {
+            mListener = listener;
             mHandler = handler;
         }
 
@@ -295,7 +304,7 @@
                             for (int i = 0; i < size; i++) {
                                 controllers.add(new MediaController(mContext, tokens.get(i)));
                             }
-                            SessionListener.this.onActiveSessionsChanged(controllers);
+                            mListener.onActiveSessionsChanged(controllers);
                         }
                     });
                 }
diff --git a/media/java/android/media/session/ParcelableVolumeInfo.java b/media/java/android/media/session/ParcelableVolumeInfo.java
index e71b539..96a45d9b 100644
--- a/media/java/android/media/session/ParcelableVolumeInfo.java
+++ b/media/java/android/media/session/ParcelableVolumeInfo.java
@@ -21,7 +21,7 @@
 
 /**
  * Convenience class for passing information about the audio configuration of a
- * session. The public implementation is {@link MediaController.VolumeInfo}.
+ * session. The public implementation is {@link MediaController.AudioInfo}.
  *
  * @hide
  */
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 2ad8eae..566e218 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -120,11 +120,11 @@
     public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11;
 
     /**
-     * Indicates this performer supports the skip to track command.
+     * Indicates this performer supports the skip to item command.
      *
      * @see Builder#setActions(long)
      */
-    public static final long ACTION_SKIP_TO_TRACK = 1 << 12;
+    public static final long ACTION_SKIP_TO_ITEM = 1 << 12;
 
     /**
      * This is the default playback state and indicates that no media has been
@@ -223,11 +223,11 @@
     private List<PlaybackState.CustomAction> mCustomActions;
     private final CharSequence mErrorMessage;
     private final long mUpdateTime;
-    private final long mActiveTrackId;
+    private final long mActiveItemId;
 
     private PlaybackState(int state, long position, long updateTime, float speed,
             long bufferPosition, long transportControls,
-            List<PlaybackState.CustomAction> customActions, long activeTrackId,
+            List<PlaybackState.CustomAction> customActions, long activeItemId,
             CharSequence error) {
         mState = state;
         mPosition = position;
@@ -236,7 +236,7 @@
         mBufferPosition = bufferPosition;
         mActions = transportControls;
         mCustomActions = new ArrayList<>(customActions);
-        mActiveTrackId = activeTrackId;
+        mActiveItemId = activeItemId;
         mErrorMessage = error;
     }
 
@@ -248,7 +248,7 @@
         mBufferPosition = in.readLong();
         mActions = in.readLong();
         mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
-        mActiveTrackId = in.readLong();
+        mActiveItemId = in.readLong();
         mErrorMessage = in.readCharSequence();
 
     }
@@ -263,7 +263,7 @@
         bob.append(", updated=").append(mUpdateTime);
         bob.append(", actions=").append(mActions);
         bob.append(", custom actions=").append(mCustomActions);
-        bob.append(", active track id=").append(mActiveTrackId);
+        bob.append(", active item id=").append(mActiveItemId);
         bob.append(", error=").append(mErrorMessage);
         bob.append("}");
         return bob.toString();
@@ -283,7 +283,7 @@
         dest.writeLong(mBufferPosition);
         dest.writeLong(mActions);
         dest.writeTypedList(mCustomActions);
-        dest.writeLong(mActiveTrackId);
+        dest.writeLong(mActiveItemId);
         dest.writeCharSequence(mErrorMessage);
     }
 
@@ -716,7 +716,7 @@
         private long mActions;
         private CharSequence mErrorMessage;
         private long mUpdateTime;
-        private long mActiveTrackId = MediaSession.Track.UNKNOWN_ID;
+        private long mActiveItemId = MediaSession.Item.UNKNOWN_ID;
 
         /**
          * Creates an initially empty state builder.
@@ -744,14 +744,14 @@
             }
             mErrorMessage = from.mErrorMessage;
             mUpdateTime = from.mUpdateTime;
-            mActiveTrackId = from.mActiveTrackId;
+            mActiveItemId = from.mActiveItemId;
         }
 
         /**
          * Set the current state of playback.
          * <p>
          * The position must be in ms and indicates the current playback
-         * position within the track. If the position is unknown use
+         * position within the item. If the position is unknown use
          * {@link #PLAYBACK_POSITION_UNKNOWN}. When not using an unknown
          * position the time at which the position was updated must be provided.
          * It is okay to use {@link SystemClock#elapsedRealtime()} if the
@@ -773,7 +773,7 @@
          * </ul>
          *
          * @param state The current state of playback.
-         * @param position The position in the current track in ms.
+         * @param position The position in the current item in ms.
          * @param playbackSpeed The current speed of playback as a multiple of
          *            normal playback.
          * @param updateTime The time in the {@link SystemClock#elapsedRealtime}
@@ -792,7 +792,7 @@
          * Set the current state of playback.
          * <p>
          * The position must be in ms and indicates the current playback
-         * position within the track. If the position is unknown use
+         * position within the item. If the position is unknown use
          * {@link #PLAYBACK_POSITION_UNKNOWN}. The update time will be set to
          * the current {@link SystemClock#elapsedRealtime()}.
          * <p>
@@ -812,7 +812,7 @@
          * </ul>
          *
          * @param state The current state of playback.
-         * @param position The position in the current track in ms.
+         * @param position The position in the current item in ms.
          * @param playbackSpeed The current speed of playback as a multiple of
          *            normal playback.
          * @return this
@@ -902,14 +902,14 @@
         }
 
         /**
-         * Set the active track in the play queue by specifying its id.
-         * The default value is {@link MediaSession.Track#UNKNOWN_ID}
+         * Set the active item in the play queue by specifying its id. The
+         * default value is {@link MediaSession.Item#UNKNOWN_ID}
          *
-         * @param id The id of the active track.
+         * @param id The id of the active item.
          * @return this
          */
-        public Builder setActiveTrack(long id) {
-            mActiveTrackId = id;
+        public Builder setActiveItem(long id) {
+            mActiveItemId = id;
             return this;
         }
 
@@ -932,7 +932,7 @@
          */
         public PlaybackState build() {
             return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferPosition,
-                    mActions, mCustomActions, mActiveTrackId, mErrorMessage);
+                    mActions, mCustomActions, mActiveItemId, mErrorMessage);
         }
     }
 }
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 445194e..f348b9b 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -59,19 +59,6 @@
     // STOPSHIP: Turn debugging off.
     private static final boolean DEBUG = true;
 
-    /**
-     * Passed with {@link TvInputListener#onError(String, int)}. Indicates that the connection to
-     * the requested TV input was not established thus the view is unable to handle the further
-     * operations.
-     */
-    public static final int ERROR_INPUT_NOT_CONNECTED = 0;
-
-    /**
-     * Passed with {@link TvInputListener#onError(String, int)}. Indicates that the underlying TV
-     * input has been disconnected.
-     */
-    public static final int ERROR_INPUT_DISCONNECTED = 1;
-
     private static final int VIDEO_SIZE_VALUE_UNKNOWN = 0;
 
     private static final int ZORDER_MEDIA = 0;
@@ -686,13 +673,20 @@
     public abstract static class TvInputListener {
 
         /**
-         * This is invoked when an error occurred while handling requested operation.
+         * This is invoked when an error occurred while establishing a connection to the underlying
+         * TV input.
          *
          * @param inputId The ID of the TV input bound to this view.
-         * @param errorCode The error code. For the details of error code, please see
-         *         {@link TvView}.
          */
-        public void onError(String inputId, int errorCode) {
+        public void onConnectionFailed(String inputId) {
+        }
+
+        /**
+         * This is invoked when the existing connection to the underlying TV input is lost.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         */
+        public void onDisconnected(String inputId) {
         }
 
         /**
@@ -857,7 +851,7 @@
                 }
             } else {
                 if (mListener != null) {
-                    mListener.onError(mInputId, ERROR_INPUT_NOT_CONNECTED);
+                    mListener.onConnectionFailed(mInputId);
                 }
             }
         }
@@ -870,7 +864,7 @@
             mSessionCallback = null;
             mSession = null;
             if (mListener != null) {
-                mListener.onError(mInputId, ERROR_INPUT_DISCONNECTED);
+                mListener.onDisconnected(mInputId);
             }
         }
 
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index db319e9..08702291 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -16,7 +16,10 @@
 
 <resources>
 
-    <style name="PrintActivity" parent="@android:style/Theme.Material.Settings">
+    <style name="PrintActivity" parent="@android:style/Theme.Material">
+        <item name="android:colorPrimary">@*android:color/material_blue_grey_900</item>
+        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
+        <item name="android:colorAccent">@*android:color/material_deep_teal_A500</item>
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowContentOverlay">@null</item>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 6f41565..f1d2bee3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -90,6 +90,7 @@
     <uses-permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN" />
     <uses-permission android:name="android.permission.FRAME_STATS" />
     <uses-permission android:name="android.permission.BIND_APPWIDGET" />
+    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
 
     <application android:label="@string/app_label">
         <provider
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 828065b..5253ee0 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -69,6 +69,7 @@
         android:layout_gravity="bottom|right"
         android:layout_marginRight="15dp"
         android:layout_marginBottom="15dp"
+        android:translationZ="3dp"
         android:contentDescription="@string/recents_lock_to_app_button_label"
         android:background="@drawable/recents_lock_to_task_button_bg">
         <ImageView
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5415d19..1b8eeb2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -205,10 +205,10 @@
     <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
 
     <!-- The min translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_min">5dp</dimen>
+    <dimen name="recents_task_view_z_min">25dp</dimen>
 
     <!-- The max translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_max">65dp</dimen>
+    <dimen name="recents_task_view_z_max">100dp</dimen>
 
     <!-- The amount to translate when animating the removal of a task. -->
     <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1bd0561..d49312d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -707,10 +707,13 @@
     <string name="guest_exit_guest">Remove guest</string>
 
     <!-- Title of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
-    <string name="guest_exit_guest_dialog_title">Exiting guest session?</string>
+    <string name="guest_exit_guest_dialog_title">Remove guest?</string>
 
     <!-- Message of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
-    <string name="guest_exit_guest_dialog_message">Exiting the guest session will remove local data.</string>
+    <string name="guest_exit_guest_dialog_message">All apps and data in this session will be deleted.</string>
+
+    <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
+    <string name="guest_exit_guest_dialog_remove">Remove</string>
 
     <!-- Title of the notification when resuming an existing guest session [CHAR LIMIT=NONE] -->
     <string name="guest_wipe_session_title">Welcome back, guest!</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 27e58a4..48a031a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -21,11 +21,23 @@
     </style>
 
     <!-- Alternate Recents theme -->
-    <style name="RecentsTheme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
+    <style name="RecentsTheme" parent="@android:style/Theme">
+        <!-- NoTitle -->
+        <item name="android:windowNoTitle">true</item>
+        <!-- Wallpaper -->
+        <item name="android:windowBackground">@color/transparent</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowShowWallpaper">true</item>
+        <!-- Misc -->
         <item name="android:statusBarColor">@android:color/transparent</item>
         <item name="android:navigationBarColor">@android:color/transparent</item>
         <item name="android:windowDrawsSystemBarBackgrounds">true</item>
         <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
+        <item name="*android:lightingStyle">@style/RecentsLighting</item>
+    </style>
+
+    <style name="RecentsLighting" parent="@*android:style/Lighting">
+        <item name="*android:ambientShadowAlpha">0.30</item>
     </style>
 
     <!-- Animations for a non-full-screen window or activity. -->
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
index 667faa7..f0bdfa2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -53,7 +53,7 @@
 
     // Log function
     static final float XScale = 1.75f;  // The large the XScale, the longer the flat area of the curve
-    static final float LogBase = 300;
+    static final float LogBase = 3000;
     static final int PrecisionSteps = 250;
     static float[] xp;
     static float[] px;
@@ -84,7 +84,7 @@
                 left + size, mStackRect.top + size);
 
         // Update the affiliation offsets
-        float visibleTaskPct = 0.55f;
+        float visibleTaskPct = 0.5f;
         mWithinAffiliationOffset = mConfig.taskBarHeight;
         mBetweenAffiliationOffset = (int) (visibleTaskPct * mTaskRect.height());
     }
@@ -312,4 +312,4 @@
         }
         return px[xFloorIndex] + pFraction;
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 5914b39..e514c90 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -21,12 +21,14 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewOutlineProvider;
 import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
@@ -57,7 +59,7 @@
     ObjectAnimator mDimAnimator;
     float mMaxDimScale;
     int mDim;
-    AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1.25f);
+    AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1f);
     PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.MULTIPLY);
 
     Task mTask;
@@ -129,6 +131,14 @@
         mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar);
         mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail);
         mActionButtonView = findViewById(R.id.lock_to_app_fab);
+        mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                // Set the outline to match the FAB background
+                outline.setOval(0, 0, mActionButtonView.getWidth(),
+                        mActionButtonView.getHeight());
+            }
+        });
         if (mFooterView != null) {
             mFooterView.setCallbacks(this);
         }
@@ -469,7 +479,8 @@
             boolean occludesLaunchTarget) {
         if (isLaunchingTask) {
             // Disable the thumbnail clip and animate the bar out for the window animation out
-            mHeaderView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r);
+            mHeaderView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r,
+                    mIsFocused);
             // Animate the thumbnail alpha back into full opacity for the window animation out
             mThumbnailView.startLaunchTaskAnimation();
 
@@ -624,7 +635,7 @@
     public void setDim(int dim) {
         mDim = dim;
         // Defer setting hardware layers if we have not yet measured, or there is no dim to draw
-        if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0 && dim > 0) {
+        if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
             if (mDimAnimator != null) {
                 mDimAnimator.removeAllListeners();
                 mDimAnimator.cancel();
@@ -828,6 +839,10 @@
                 } else if (v == mHeaderView.mDismissButton) {
                     dismissTask();
                 } else {
+                    if (v == mActionButtonView) {
+                        // Reset the translation of the action button before we animate it out
+                        mActionButtonView.setTranslationZ(0f);
+                    }
                     mCb.onTaskViewClicked(tv, tv.getTask(),
                             (v == mFooterView || v == mActionButtonView));
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 4b09549..c7198fe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -18,7 +18,9 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -59,7 +61,8 @@
     ColorDrawable mBackgroundColor;
     Drawable mLightDismissDrawable;
     Drawable mDarkDismissDrawable;
-    ValueAnimator mBackgroundColorAnimator;
+    AnimatorSet mFocusAnimator;
+    ValueAnimator backgroundColorAnimator;
 
     boolean mIsFullscreen;
     boolean mCurrentPrimaryColorIsDark;
@@ -117,6 +120,14 @@
 
     @Override
     protected void onFinishInflate() {
+        // Set the outline provider
+        setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
+            }
+        });
+
         // Initialize the icon and description views
         mApplicationIcon = (ImageView) findViewById(R.id.application_icon);
         mActivityDescription = (TextView) findViewById(R.id.activity_description);
@@ -211,23 +222,29 @@
     void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) {
         // Animate the task bar of the first task view
         setVisibility(View.VISIBLE);
-        setTranslationY(-getMeasuredHeight());
+        setAlpha(0f);
         animate()
-                .translationY(0)
+                .alpha(1f)
                 .setStartDelay(delay)
-                .setInterpolator(mConfig.fastOutSlowInInterpolator)
+                .setInterpolator(mConfig.linearOutSlowInInterpolator)
                 .setDuration(mConfig.taskBarEnterAnimDuration)
                 .withEndAction(postAnimRunnable)
+                .withLayer()
                 .start();
     }
 
     /** Animates this task bar as it exits recents */
-    void startLaunchTaskAnimation(Runnable preAnimRunnable, final Runnable postAnimRunnable) {
+    void startLaunchTaskAnimation(Runnable preAnimRunnable, final Runnable postAnimRunnable,
+            boolean isFocused) {
+        if (isFocused) {
+            onTaskViewFocusChanged(false);
+        }
+
         // Animate the task bar out of the first task view
         animate()
-                .translationY(-getMeasuredHeight())
+                .alpha(0f)
                 .setStartDelay(0)
-                .setInterpolator(mConfig.fastOutLinearInInterpolator)
+                .setInterpolator(mConfig.linearOutSlowInInterpolator)
                 .setDuration(mConfig.taskBarExitAnimDuration)
                 .withStartAction(preAnimRunnable)
                 .withEndAction(new Runnable() {
@@ -236,6 +253,7 @@
                         post(postAnimRunnable);
                     }
                 })
+                .withLayer()
                 .start();
     }
 
@@ -278,10 +296,10 @@
     /** Notifies the associated TaskView has been focused. */
     void onTaskViewFocusChanged(boolean focused) {
         boolean isRunning = false;
-        if (mBackgroundColorAnimator != null) {
-            isRunning = mBackgroundColorAnimator.isRunning();
-            mBackgroundColorAnimator.removeAllUpdateListeners();
-            mBackgroundColorAnimator.cancel();
+        if (mFocusAnimator != null) {
+            isRunning = mFocusAnimator.isRunning();
+            mFocusAnimator.removeAllListeners();
+            mFocusAnimator.cancel();
         }
         if (focused) {
             int secondaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
@@ -302,42 +320,54 @@
             // Pulse the background color
             int currentColor = mBackgroundColor.getColor();
             int lightPrimaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
-            mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), lightPrimaryColor,
-                    currentColor);
-            mBackgroundColorAnimator.addListener(new AnimatorListenerAdapter() {
+            ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(),
+                    lightPrimaryColor, currentColor);
+            backgroundColor.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationStart(Animator animation) {
-                    mBackground.setState(new int[] {});
+                    mBackground.setState(new int[]{});
                 }
             });
-            mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            backgroundColor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
                     mBackgroundColor.setColor((Integer) animation.getAnimatedValue());
                 }
             });
-            mBackgroundColorAnimator.setRepeatCount(ValueAnimator.INFINITE);
-            mBackgroundColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
-            mBackgroundColorAnimator.setStartDelay(750);
-            mBackgroundColorAnimator.setDuration(750);
-            mBackgroundColorAnimator.start();
+            backgroundColor.setRepeatCount(ValueAnimator.INFINITE);
+            backgroundColor.setRepeatMode(ValueAnimator.REVERSE);
+            // Pulse the translation
+            ObjectAnimator translation = ObjectAnimator.ofFloat(this, "translationZ", 15f);
+            translation.setRepeatCount(ValueAnimator.INFINITE);
+            translation.setRepeatMode(ValueAnimator.REVERSE);
+
+            mFocusAnimator = new AnimatorSet();
+            mFocusAnimator.playTogether(backgroundColor, translation);
+            mFocusAnimator.setStartDelay(750);
+            mFocusAnimator.setDuration(750);
+            mFocusAnimator.start();
         } else {
             if (isRunning) {
                 // Restore the background color
                 int currentColor = mBackgroundColor.getColor();
-                mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), currentColor,
-                        mCurrentPrimaryColor);
-                mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(),
+                        currentColor, mCurrentPrimaryColor);
+                backgroundColor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                     @Override
                     public void onAnimationUpdate(ValueAnimator animation) {
                         mBackgroundColor.setColor((Integer) animation.getAnimatedValue());
                     }
                 });
-                mBackgroundColorAnimator.setRepeatCount(0);
-                mBackgroundColorAnimator.setDuration(150);
-                mBackgroundColorAnimator.start();
+                // Restore the translation
+                ObjectAnimator translation = ObjectAnimator.ofFloat(this, "translationZ", 0f);
+
+                mFocusAnimator = new AnimatorSet();
+                mFocusAnimator.playTogether(backgroundColor, translation);
+                mFocusAnimator.setDuration(150);
+                mFocusAnimator.start();
             } else {
                 mBackground.setState(new int[] {});
+                setTranslationZ(0f);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 47e3e73..d53aa47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -508,9 +508,9 @@
             setTitle(R.string.guest_exit_guest_dialog_title);
             setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
             setButton(DialogInterface.BUTTON_NEGATIVE,
-                    context.getString(android.R.string.no), this);
+                    context.getString(android.R.string.cancel), this);
             setButton(DialogInterface.BUTTON_POSITIVE,
-                    context.getString(android.R.string.yes), this);
+                    context.getString(R.string.guest_exit_guest_dialog_remove), this);
             setCanceledOnTouchOutside(false);
             mGuestId = guestId;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index b05c242..51876b8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -37,7 +37,7 @@
 import android.media.ToneGenerator;
 import android.media.VolumeProvider;
 import android.media.session.MediaController;
-import android.media.session.MediaController.VolumeInfo;
+import android.media.session.MediaController.AudioInfo;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -537,8 +537,8 @@
             if (mStreamControls != null) {
                 StreamControl sc = mStreamControls.get(streamType);
                 if (sc != null && sc.controller != null) {
-                    VolumeInfo vi = sc.controller.getVolumeInfo();
-                    return vi.getMaxVolume();
+                    AudioInfo ai = sc.controller.getAudioInfo();
+                    return ai.getMaxVolume();
                 }
             }
             return -1;
@@ -554,8 +554,8 @@
             if (mStreamControls != null) {
                 StreamControl sc = mStreamControls.get(streamType);
                 if (sc != null && sc.controller != null) {
-                    VolumeInfo vi = sc.controller.getVolumeInfo();
-                    return vi.getCurrentVolume();
+                    AudioInfo ai = sc.controller.getAudioInfo();
+                    return ai.getCurrentVolume();
                 }
             }
             return -1;
@@ -990,7 +990,7 @@
                     // We still don't have one, ignore the command.
                     Log.w(mTag, "sent remote volume change without a controller!");
                 } else {
-                    VolumeInfo vi = controller.getVolumeInfo();
+                    AudioInfo vi = controller.getAudioInfo();
                     index = vi.getCurrentVolume();
                     max = vi.getMaxVolume();
                     if ((vi.getVolumeControl() & VolumeProvider.VOLUME_CONTROL_FIXED) != 0) {
@@ -1362,7 +1362,7 @@
     };
 
     private final MediaController.Callback mMediaControllerCb = new MediaController.Callback() {
-        public void onVolumeInfoChanged(VolumeInfo info) {
+        public void onAudioInfoChanged(AudioInfo info) {
             onRemoteVolumeUpdateIfShown();
         }
     };
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 7db85f2..3cda6de 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -1868,7 +1868,7 @@
         }
     }
 
-    static void sendBufferNotification(int id) {
+    static void sendBufferNotification(long id) {
         synchronized(mAllocationMap) {
             Allocation a = mAllocationMap.get(new Long(id));
 
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 340efef..6c5c508 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -1156,7 +1156,12 @@
                 }
 
                 if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
-                    Allocation.sendBufferNotification(subID);
+                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
+                        RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
+                        throw new RSDriverException("Error processing message from RenderScript.");
+                    }
+                    long bufferID = ((long)rbuf[1] << 32L) + ((long)rbuf[0] & 0xffffffffL);
+                    Allocation.sendBufferNotification(bufferID);
                     continue;
                 }
 
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 16df377..13a649a 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -222,7 +222,7 @@
 nDeviceCreate(JNIEnv *_env, jobject _this)
 {
     LOG_API("nDeviceCreate");
-    return (jlong)rsDeviceCreate();
+    return (jlong)(uintptr_t)rsDeviceCreate();
 }
 
 static void
@@ -243,7 +243,7 @@
 nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
 {
     LOG_API("nContextCreate");
-    return (jlong)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
+    return (jlong)(uintptr_t)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
 }
 
 static jlong
@@ -267,7 +267,7 @@
     sc.samplesQ = samplesQ;
 
     LOG_API("nContextCreateGL");
-    return (jlong)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
+    return (jlong)(uintptr_t)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
 }
 
 static void
@@ -409,7 +409,7 @@
 nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
 {
     LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con, type, kind, norm, size);
-    return (jlong)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
+    return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
 }
 
 static jlong
@@ -435,7 +435,7 @@
     const char **nameArray = names.c_str();
     size_t *sizeArray = names.c_str_len();
 
-    jlong id = (jlong)rsElementCreate2((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
                                      (const RsElement *)ids, fieldCount,
                                      nameArray, fieldCount * sizeof(size_t),  sizeArray,
                                      (const uint32_t *)arraySizes, fieldCount);
@@ -445,7 +445,7 @@
     _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
     _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
 
-    return (jlong)id;
+    return (jlong)(uintptr_t)id;
 }
 
 static void
@@ -483,7 +483,7 @@
     rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
 
     for(uint32_t i = 0; i < dataSize; i++) {
-        const jlong id = (jlong)ids[i];
+        const jlong id = (jlong)(uintptr_t)ids[i];
         const jint arraySize = (jint)arraySizes[i];
         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
         _env->SetLongArrayRegion(_IDs, i, 1, &id);
@@ -504,7 +504,7 @@
     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
             (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
 
-    return (jlong)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
+    return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
 }
 
 static void
@@ -521,7 +521,7 @@
     rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
 
     for(jint i = 0; i < elementCount; i ++) {
-        const jlong data = (jlong)typeData[i];
+        const jlong data = (jlong)(uintptr_t)typeData[i];
         _env->SetLongArrayRegion(_typeData, i, 1, &data);
     }
 }
@@ -532,7 +532,7 @@
 nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jlong pointer)
 {
     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
-    return (jlong) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
+    return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
 }
 
 static void
@@ -600,7 +600,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jlong id = (jlong)rsAllocationCreateFromBitmap((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
                                                   (RsType)type, (RsAllocationMipmapControl)mip,
                                                   ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
@@ -616,7 +616,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jlong id = (jlong)rsAllocationCreateTyped((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
                                             (RsType)type, (RsAllocationMipmapControl)mip,
                                             (uint32_t)usage, (uintptr_t)ptr);
     bitmap.unlockPixels();
@@ -632,7 +632,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jlong id = (jlong)rsAllocationCubeCreateFromBitmap((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
                                                       (RsType)type, (RsAllocationMipmapControl)mip,
                                                       ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
@@ -810,7 +810,7 @@
 nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
 {
     LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
-    return (jlong) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
+    return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
 }
 
 static void
@@ -828,7 +828,7 @@
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
     ALOGV("______nFileA3D %p", asset);
 
-    jlong id = (jlong)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
+    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
     return id;
 }
 
@@ -846,7 +846,7 @@
         return 0;
     }
 
-    jlong id = (jlong)rsaFileA3DCreateFromAsset((RsContext)con, asset);
+    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
     return id;
 }
 
@@ -854,7 +854,7 @@
 nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
 {
     AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
-    jlong id = (jlong)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
+    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
 
     return id;
 }
@@ -887,7 +887,7 @@
 nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
 {
     ALOGV("______nFileA3D %p", (RsFile) fileA3D);
-    jlong id = (jlong)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
+    jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
     return id;
 }
 
@@ -898,7 +898,7 @@
                     jstring fileName, jfloat fontSize, jint dpi)
 {
     AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
-    jlong id = (jlong)rsFontCreateFromFile((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
                                          fileNameUTF.c_str(), fileNameUTF.length(),
                                          fontSize, dpi);
 
@@ -912,7 +912,7 @@
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
     AutoJavaStringToUTF8 nameUTF(_env, name);
 
-    jlong id = (jlong)rsFontCreateFromMemory((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
                                            nameUTF.c_str(), nameUTF.length(),
                                            fontSize, dpi,
                                            asset->getBuffer(false), asset->getLength());
@@ -934,7 +934,7 @@
         return 0;
     }
 
-    jlong id = (jlong)rsFontCreateFromMemory((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
                                            str.c_str(), str.length(),
                                            fontSize, dpi,
                                            asset->getBuffer(false), asset->getLength());
@@ -1283,7 +1283,7 @@
 
     //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
 
-    ret = (jlong)rsScriptCCreate((RsContext)con,
+    ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
                                 resNameUTF.c_str(), resNameUTF.length(),
                                 cacheDirUTF.c_str(), cacheDirUTF.length(),
                                 (const char *)script_ptr, length);
@@ -1294,28 +1294,28 @@
                 _exception ? JNI_ABORT: 0);
     }
 
-    return (jlong)ret;
+    return (jlong)(uintptr_t)ret;
 }
 
 static jlong
 nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
 {
     LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
-    return (jlong)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
+    return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
 }
 
 static jlong
 nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
 {
     LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con, (void *)sid, slot, sig);
-    return (jlong)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
+    return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
 }
 
 static jlong
 nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
 {
     LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
-    return (jlong)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
+    return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
 }
 
 static jlong
@@ -1359,7 +1359,7 @@
         typesPtr[i] = (RsType)jTypesPtr[i];
     }
 
-    jlong id = (jlong)rsScriptGroupCreate((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
                                (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
                                (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
                                (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
@@ -1412,7 +1412,7 @@
                     jint depthFunc)
 {
     LOG_API("nProgramStoreCreate, con(%p)", (RsContext)con);
-    return (jlong)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
                                       depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
                                       (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
 }
@@ -1461,7 +1461,7 @@
     for(int i = 0; i < paramLen; ++i) {
         paramPtr[i] = (uintptr_t)jParamPtr[i];
     }
-    jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
+    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
                                              nameArray, texCount, sizeArray,
                                              paramPtr, paramLen);
 
@@ -1493,7 +1493,7 @@
         paramPtr[i] = (uintptr_t)jParamPtr[i];
     }
 
-    jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
+    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
                                            nameArray, texCount, sizeArray,
                                            paramPtr, paramLen);
 
@@ -1508,7 +1508,7 @@
 nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
 {
     LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con, pointSprite, cull);
-    return (jlong)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
+    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
 }
 
 
@@ -1557,7 +1557,7 @@
                jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
 {
     LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
-    return (jlong)rsSamplerCreate((RsContext)con,
+    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
                                  (RsSamplerValue)magFilter,
                                  (RsSamplerValue)minFilter,
                                  (RsSamplerValue)wrapS,
@@ -1572,7 +1572,7 @@
 nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jlong _loop, jfloat q) {
     LOG_API("nPathCreate, con(%p)", (RsContext)con);
 
-    jlong id = (jlong)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
+    jlong id = (jlong)(uintptr_t)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
                                    (RsAllocation)_vtx,
                                    (RsAllocation)_loop, q);
     return id;
@@ -1600,7 +1600,7 @@
     jint primLen = _env->GetArrayLength(_prim);
     jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
 
-    jlong id = (jlong)rsMeshCreate((RsContext)con,
+    jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
                                (RsAllocation *)vtxPtr, vtxLen,
                                (RsAllocation *)idxPtr, idxLen,
                                (uint32_t *)primPtr, primLen);
@@ -1640,7 +1640,7 @@
     rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
 
     for(jint i = 0; i < numVtxIDs; i ++) {
-        const jlong alloc = (jlong)allocs[i];
+        const jlong alloc = (jlong)(uintptr_t)allocs[i];
         _env->SetLongArrayRegion(_ids, i, 1, &alloc);
     }
 
@@ -1658,7 +1658,7 @@
     rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
 
     for(jint i = 0; i < numIndices; i ++) {
-        const jlong alloc = (jlong)allocs[i];
+        const jlong alloc = (jlong)(uintptr_t)allocs[i];
         const jint prim = (jint)prims[i];
         _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
         _env->SetIntArrayRegion(_primitives, i, 1, &prim);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index e528d57..abacb2d 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -575,6 +575,10 @@
 
     void makeFinishing() {
         if (!finishing) {
+            if (this == task.stack.getVisibleBehindActivity()) {
+                // A finishing activity should not remain as visible in the background
+                mStackSupervisor.requestVisibleBehindLocked(this, false);
+            }
             finishing = true;
             if (stopped) {
                 clearOptionsLocked();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1107139..931f448 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2659,13 +2659,20 @@
         }
 
         // A non-top activity is reporting a visibility change.
-        if (top.fullscreen || top.state != ActivityState.RESUMED || top.app == null ||
-                top.app.thread == null) {
+        if ((visible && (top.fullscreen || top.state != ActivityState.RESUMED)) ||
+                top.app == null || top.app.thread == null) {
             // Can't carry out this request.
             if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen="
-                    + top.fullscreen+ " top.state=" + top.state + " top.app=" + top.app +
+                    + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app +
                     " top.app.thread=" + top.app.thread);
             return false;
+        } else if (!visible && stack.getVisibleBehindActivity() != r) {
+            // Only the activity set as currently visible behind should actively reset its
+            // visible behind state.
+            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning visible="
+                    + visible + " stack.getVisibleBehindActivity()=" +
+                    stack.getVisibleBehindActivity() + " r=" + r);
+            return false;
         }
 
         stack.setVisibleBehindActivity(visible ? r : null);
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index 907eeb2..857b9e9 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -20,10 +20,10 @@
 import android.net.IpConfiguration.IpAssignment;
 import android.net.IpConfiguration.ProxySettings;
 import android.net.LinkAddress;
-import android.net.LinkProperties;
 import android.net.NetworkUtils;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.text.TextUtils;
@@ -41,6 +41,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.Inet4Address;
 import java.util.Map;
 
 public class IpConfigStore {
@@ -69,40 +70,32 @@
     }
 
     private boolean writeConfig(DataOutputStream out, int configKey,
-                                  IpConfiguration config) throws IOException {
+                                IpConfiguration config) throws IOException {
         boolean written = false;
 
         try {
-            LinkProperties linkProperties = config.linkProperties;
             switch (config.ipAssignment) {
                 case STATIC:
                     out.writeUTF(IP_ASSIGNMENT_KEY);
                     out.writeUTF(config.ipAssignment.toString());
-                    for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
-                        out.writeUTF(LINK_ADDRESS_KEY);
-                        out.writeUTF(linkAddr.getAddress().getHostAddress());
-                        out.writeInt(linkAddr.getPrefixLength());
-                    }
-                    for (RouteInfo route : linkProperties.getRoutes()) {
-                        out.writeUTF(GATEWAY_KEY);
-                        LinkAddress dest = route.getDestinationLinkAddress();
-                        if (dest != null) {
-                            out.writeInt(1);
-                            out.writeUTF(dest.getAddress().getHostAddress());
-                            out.writeInt(dest.getPrefixLength());
-                        } else {
-                            out.writeInt(0);
+                    StaticIpConfiguration staticIpConfiguration = config.staticIpConfiguration;
+                    if (staticIpConfiguration != null) {
+                        if (staticIpConfiguration.ipAddress != null) {
+                            LinkAddress ipAddress = staticIpConfiguration.ipAddress;
+                            out.writeUTF(LINK_ADDRESS_KEY);
+                            out.writeUTF(ipAddress.getAddress().getHostAddress());
+                            out.writeInt(ipAddress.getPrefixLength());
                         }
-                        if (route.getGateway() != null) {
-                            out.writeInt(1);
-                            out.writeUTF(route.getGateway().getHostAddress());
-                        } else {
-                            out.writeInt(0);
+                        if (staticIpConfiguration.gateway != null) {
+                            out.writeUTF(GATEWAY_KEY);
+                            out.writeInt(0);  // Default route.
+                            out.writeInt(1);  // Have a gateway.
+                            out.writeUTF(staticIpConfiguration.gateway.getHostAddress());
                         }
-                    }
-                    for (InetAddress inetAddr : linkProperties.getDnsServers()) {
-                        out.writeUTF(DNS_KEY);
-                        out.writeUTF(inetAddr.getHostAddress());
+                        for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
+                            out.writeUTF(DNS_KEY);
+                            out.writeUTF(inetAddr.getHostAddress());
+                        }
                     }
                     written = true;
                     break;
@@ -121,7 +114,7 @@
 
             switch (config.proxySettings) {
                 case STATIC:
-                    ProxyInfo proxyProperties = linkProperties.getHttpProxy();
+                    ProxyInfo proxyProperties = config.httpProxy;
                     String exclusionList = proxyProperties.getExclusionListAsString();
                     out.writeUTF(PROXY_SETTINGS_KEY);
                     out.writeUTF(config.proxySettings.toString());
@@ -134,7 +127,7 @@
                     written = true;
                     break;
                 case PAC:
-                    ProxyInfo proxyPacProperties = linkProperties.getHttpProxy();
+                    ProxyInfo proxyPacProperties = config.httpProxy;
                     out.writeUTF(PROXY_SETTINGS_KEY);
                     out.writeUTF(config.proxySettings.toString());
                     out.writeUTF(PROXY_PAC_FILE);
@@ -159,7 +152,7 @@
                 out.writeInt(configKey);
             }
         } catch (NullPointerException e) {
-            loge("Failure in writing " + config.linkProperties + e);
+            loge("Failure in writing " + config + e);
         }
         out.writeUTF(EOS);
 
@@ -196,7 +189,7 @@
                 // Default is DHCP with no proxy
                 IpAssignment ipAssignment = IpAssignment.DHCP;
                 ProxySettings proxySettings = ProxySettings.NONE;
-                LinkProperties linkProperties = new LinkProperties();
+                StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
                 String proxyHost = null;
                 String pacFileUrl = null;
                 int proxyPort = -1;
@@ -213,13 +206,23 @@
                         } else if (key.equals(LINK_ADDRESS_KEY)) {
                             LinkAddress linkAddr = new LinkAddress(
                                     NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());
-                            linkProperties.addLinkAddress(linkAddr);
+                            if (linkAddr.getAddress() instanceof Inet4Address &&
+                                    staticIpConfiguration.ipAddress == null) {
+                                staticIpConfiguration.ipAddress = linkAddr;
+                            } else {
+                                loge("Non-IPv4 or duplicate address: " + linkAddr);
+                            }
                         } else if (key.equals(GATEWAY_KEY)) {
                             LinkAddress dest = null;
                             InetAddress gateway = null;
                             if (version == 1) {
                                 // only supported default gateways - leave the dest/prefix empty
                                 gateway = NetworkUtils.numericToInetAddress(in.readUTF());
+                                if (staticIpConfiguration.gateway == null) {
+                                    staticIpConfiguration.gateway = gateway;
+                                } else {
+                                    loge("Duplicate gateway: " + gateway.getHostAddress());
+                                }
                             } else {
                                 if (in.readInt() == 1) {
                                     dest = new LinkAddress(
@@ -229,10 +232,16 @@
                                 if (in.readInt() == 1) {
                                     gateway = NetworkUtils.numericToInetAddress(in.readUTF());
                                 }
+                                RouteInfo route = new RouteInfo(dest, gateway);
+                                if (route.isIPv4Default() &&
+                                        staticIpConfiguration.gateway == null) {
+                                    staticIpConfiguration.gateway = gateway;
+                                } else {
+                                    loge("Non-IPv4 default or duplicate route: " + route);
+                                }
                             }
-                            linkProperties.addRoute(new RouteInfo(dest, gateway));
                         } else if (key.equals(DNS_KEY)) {
-                            linkProperties.addDnsServer(
+                            staticIpConfiguration.dnsServers.add(
                                     NetworkUtils.numericToInetAddress(in.readUTF()));
                         } else if (key.equals(PROXY_SETTINGS_KEY)) {
                             proxySettings = ProxySettings.valueOf(in.readUTF());
@@ -258,9 +267,11 @@
                     IpConfiguration config = new IpConfiguration();
                     networks.put(id, config);
 
-                    config.linkProperties = linkProperties;
                     switch (ipAssignment) {
                         case STATIC:
+                            config.staticIpConfiguration = staticIpConfiguration;
+                            config.ipAssignment = ipAssignment;
+                            break;
                         case DHCP:
                             config.ipAssignment = ipAssignment;
                             break;
@@ -276,16 +287,15 @@
 
                     switch (proxySettings) {
                         case STATIC:
-                            config.proxySettings = proxySettings;
-                            ProxyInfo ProxyInfo =
+                            ProxyInfo proxyInfo =
                                     new ProxyInfo(proxyHost, proxyPort, exclusionList);
-                            linkProperties.setHttpProxy(ProxyInfo);
+                            config.proxySettings = proxySettings;
+                            config.httpProxy = proxyInfo;
                             break;
                         case PAC:
+                            ProxyInfo proxyPacProperties = new ProxyInfo(pacFileUrl);
                             config.proxySettings = proxySettings;
-                            ProxyInfo proxyPacProperties =
-                                    new ProxyInfo(pacFileUrl);
-                            linkProperties.setHttpProxy(proxyPacProperties);
+                            config.httpProxy = proxyPacProperties;
                             break;
                         case NONE:
                             config.proxySettings = proxySettings;
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 1b59f52..97f0a1e 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -16,8 +16,6 @@
 
 package com.android.server.notification;
 
-import android.os.IBinder;
-
 public interface NotificationDelegate {
     void onSetDisabled(int status);
     void onClearAll(int callingUid, int callingPid, int userId);
@@ -29,7 +27,6 @@
             int uid, int initialPid, String message, int userId);
     void onPanelRevealed();
     void onPanelHidden();
-    boolean allowDisable(int what, IBinder token, String pkg);
     void onNotificationVisibilityChanged(
             String[] newlyVisibleKeys, String[] noLongerVisibleKeys);
     void onNotificationExpansionChanged(String key, boolean userAction, boolean expanded);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f2ac963..7117933 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -29,7 +29,6 @@
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
 import android.app.Notification;
-import android.app.Notification.Builder;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
@@ -50,7 +49,6 @@
 import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -585,11 +583,6 @@
         }
 
         @Override
-        public boolean allowDisable(int what, IBinder token, String pkg) {
-            return mZenModeHelper.allowDisable(what, token, pkg);
-        }
-
-        @Override
         public void onNotificationVisibilityChanged(
                 String[] newlyVisibleKeys, String[] noLongerVisibleKeys) {
             // Using ';' as separator since eventlogs uses ',' to separate
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 525f5f8..f84409e 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -30,10 +30,7 @@
 
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
-import java.util.Arrays;
 import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
 
 public class ZenLog {
     private static final String TAG = "ZenLog";
@@ -45,10 +42,6 @@
     private static final String[] MSGS = new String[SIZE];
 
     private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
-    private static final Set<String> SYSTEM_PACKAGES = new HashSet<String>(Arrays.asList(
-            "android",
-            "com.android.systemui"
-            ));
 
     private static final int TYPE_INTERCEPTED = 1;
     private static final int TYPE_ALLOW_DISABLE = 2;
@@ -76,11 +69,6 @@
         append(TYPE_NOT_INTERCEPTED, record.getKey() + "," + reason);
     }
 
-    public static void traceAllowDisable(String pkg, boolean allowDisable, String reason) {
-        if (SYSTEM_PACKAGES.contains(pkg)) return;
-        append(TYPE_ALLOW_DISABLE, allowDisable + "," + pkg + "," + reason);
-    }
-
     public static void traceSetRingerMode(int ringerMode) {
         append(TYPE_SET_RINGER_MODE, ringerModeToString(ringerMode));
     }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 758f334..0b93690 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -35,7 +35,6 @@
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
@@ -265,18 +264,6 @@
         dispatchOnZenModeChanged();
     }
 
-    public boolean allowDisable(int what, IBinder token, String pkg) {
-        // TODO(cwren): delete this API before the next release. Bug:15344099
-        boolean allowDisable = true;
-        String reason = null;
-        if (isDefaultPhoneApp(pkg)) {
-            allowDisable = mZenMode == Global.ZEN_MODE_OFF || mConfig.allowCalls;
-            reason = mZenMode == Global.ZEN_MODE_OFF ? "zenOff" : "allowCalls";
-        }
-        ZenLog.traceAllowDisable(pkg, allowDisable, reason);
-        return allowDisable;
-    }
-
     public void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("mZenMode=");
         pw.println(Global.zenModeToString(mZenMode));
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 297dacf..f85e2d9 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -22,7 +22,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
@@ -39,9 +38,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 
 /**
@@ -187,10 +184,6 @@
 
     @Override
     public void disable(int what, IBinder token, String pkg) {
-        if (!mNotificationDelegate.allowDisable(what, token, pkg)) {
-            if (SPEW) Slog.d(TAG, "Blocking disable request from " + pkg);
-            return;
-        }
         disableInternal(mCurrentUserId, what, token, pkg);
     }
 
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 27debde..c1d5715 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -36,6 +36,15 @@
 
 /**
  * Represents a connection to a remote endpoint that carries voice traffic.
+ * <p>
+ * Implementations create a custom subclass of {@code Connection} and return it to the framework
+ * as the return value of
+ * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
+ * or
+ * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
+ * Implementations are then responsible for updating the state of the {@code Connection}, and
+ * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
+ * longer used and associated resources may be recovered.
  */
 public abstract class Connection {
 
@@ -53,10 +62,6 @@
 
     public static final int STATE_DISCONNECTED = 6;
 
-    public static final int STATE_FAILED = 7;
-
-    public static final int STATE_CANCELED = 8;
-
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
@@ -644,10 +649,6 @@
                 return "STATE_HOLDING";
             case STATE_DISCONNECTED:
                 return "DISCONNECTED";
-            case STATE_FAILED:
-                return "STATE_FAILED";
-            case STATE_CANCELED:
-                return "STATE_CANCELED";
             default:
                 Log.wtf(Connection.class, "Unknown state %d", state);
                 return "UNKNOWN";
@@ -694,33 +695,6 @@
     }
 
     /**
-     * Cancel the {@link Connection}. Once this is called, the {@link Connection} will not be used,
-     * and no subsequent {@link Connection}s will be attempted.
-     */
-    public final void setCanceled() {
-        Log.d(this, "setCanceled");
-        setState(STATE_CANCELED);
-    }
-
-    /**
-     * Move the {@link Connection} to the {@link #STATE_FAILED} state, with the given code
-     * ({@see DisconnectCause}) and message. This message is not shown to the user, but is useful
-     * for logging and debugging purposes.
-     * <p>
-     * After calling this, the {@link Connection} will not be used.
-     *
-     * @param code The {@link DisconnectCause} indicating why the connection
-     *             failed.
-     * @param message A message explaining why the {@link Connection} failed.
-     */
-    public final void setFailed(int code, String message) {
-        Log.d(this, "setFailed (%d: %s)", code, message);
-        mFailureCode = code;
-        mFailureMessage = message;
-        setState(STATE_FAILED);
-    }
-
-    /**
      * Set the video state for the connection.
      * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
      * {@link VideoProfile.VideoState#BIDIRECTIONAL},
@@ -1094,9 +1068,8 @@
     }
 
     private void setState(int state) {
-        if (mState == STATE_FAILED || mState == STATE_CANCELED) {
-            Log.d(this, "Connection already %s; cannot transition out of this state.",
-                    stateToString(mState));
+        if (mState == STATE_DISCONNECTED && mState != state) {
+            Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
             return;
         }
         if (mState != state) {
@@ -1109,33 +1082,41 @@
         }
     }
 
+    static class FailureSignalingConnection extends Connection {
+        public FailureSignalingConnection(int code, String message) {
+            setDisconnected(code, message);
+        }
+    }
+
     /**
-     * Return a {@link Connection} which represents a failed connection attempt. The returned
-     * {@link Connection} will have {@link #getFailureCode()}, {@link #getFailureMessage()}, and
-     * {@link #getState()} set appropriately, but the {@link Connection} itself should not be used
-     * for anything.
+     * Return a {@code Connection} which represents a failed connection attempt. The returned
+     * {@code Connection} will have a {@link #getFailureCode()} and {@link #getFailureMessage()}
+     * as specified, a {@link #getState()} of {@link #STATE_DISCONNECTED}.
+     * <p>
+     * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
+     * so users of this method need not maintain a reference to its return value to destroy it.
      *
      * @param code The failure code ({@see DisconnectCause}).
      * @param message A reason for why the connection failed (not intended to be shown to the user).
-     * @return A {@link Connection} which indicates failure.
+     * @return A {@code Connection} which indicates failure.
      */
     public static Connection createFailedConnection(final int code, final String message) {
-        return new Connection() {{
-            setFailed(code, message);
-        }};
+        return new FailureSignalingConnection(code, message);
     }
 
-    private static final Connection CANCELED_CONNECTION = new Connection() {{
-        setCanceled();
-    }};
+    private static final Connection CANCELED_CONNECTION =
+            new FailureSignalingConnection(DisconnectCause.OUTGOING_CANCELED, null);
 
     /**
-     * Return a {@link Connection} which represents a canceled a connection attempt. The returned
-     * {@link Connection} will have state {@link #STATE_CANCELED}, and cannot be moved out of that
-     * state. This connection should not be used for anything, and no other {@link Connection}s
-     * should be attempted.
+     * Return a {@code Connection} which represents a canceled connection attempt. The returned
+     * {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
+     * that state. This connection should not be used for anything, and no other
+     * {@code Connection}s should be attempted.
+     * <p>
+     * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
+     * so users of this method need not maintain a reference to its return value to destroy it.
      *
-     * @return A {@link Connection} which indicates that the underlying call should be canceled.
+     * @return A {@code Connection} which indicates that the underlying call should be canceled.
      */
     public static Connection createCanceledConnection() {
         return CANCELED_CONNECTION;
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 97a3102..03b6c7b 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -500,81 +500,26 @@
             boolean isIncoming) {
         Log.d(this, "call %s", request);
 
-        final Connection createdConnection;
-        if (isIncoming) {
-            createdConnection = onCreateIncomingConnection(callManagerAccount, request);
-        } else {
-            createdConnection = onCreateOutgoingConnection(callManagerAccount, request);
-        }
+        Connection createdConnection = isIncoming
+                ? onCreateIncomingConnection(callManagerAccount, request)
+                : onCreateOutgoingConnection(callManagerAccount, request);
 
-        if (createdConnection != null) {
-            Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId);
-            if (createdConnection.getState() == Connection.STATE_INITIALIZING) {
-                // Wait for the connection to become initialized.
-                createdConnection.addConnectionListener(new Connection.Listener() {
-                    @Override
-                    public void onStateChanged(Connection c, int state) {
-                        switch (state) {
-                            case Connection.STATE_FAILED:
-                                Log.d(this, "Connection (%s) failed (%d: %s)", request,
-                                        c.getFailureCode(), c.getFailureMessage());
-                                Log.d(this, "adapter handleCreateConnectionFailed %s",
-                                        callId);
-                                mAdapter.handleCreateConnectionFailed(
-                                        callId,
-                                        request,
-                                        c.getFailureCode(),
-                                        c.getFailureMessage());
-                                break;
-                            case Connection.STATE_CANCELED:
-                                Log.d(this, "adapter handleCreateConnectionCanceled %s",
-                                        callId);
-                                mAdapter.handleCreateConnectionCancelled(callId, request);
-                                break;
-                            case Connection.STATE_INITIALIZING:
-                                Log.d(this, "State changed to STATE_INITIALIZING; ignoring");
-                                return; // Don't want to stop listening on this state transition.
-                        }
-                        c.removeConnectionListener(this);
-                    }
-
-                    @Override
-                    public void onDestroyed(Connection c) {
-                        // Listen to onDestroy in case the connection is destroyed before
-                        // transitioning to another state.
-                        c.removeConnectionListener(this);
-                    }
-                });
-                Log.d(this, "Connection created in state INITIALIZING");
-                connectionCreated(callId, request, createdConnection);
-            } else if (createdConnection.getState() == Connection.STATE_CANCELED) {
-                // Tell telecomm not to attempt any more services.
-                mAdapter.handleCreateConnectionCancelled(callId, request);
-            } else if (createdConnection.getState() == Connection.STATE_FAILED) {
-                mAdapter.handleCreateConnectionFailed(
-                        callId,
-                        request,
-                        createdConnection.getFailureCode(),
-                        createdConnection.getFailureMessage());
-            } else {
-                connectionCreated(callId, request, createdConnection);
-            }
-        } else {
+        if (createdConnection == null) {
+            Log.d(this, "adapter handleCreateConnectionComplete CANCELED %s", callId);
             // Tell telecomm to try a different service.
-            Log.d(this, "adapter handleCreateConnectionFailed %s", callId);
-            mAdapter.handleCreateConnectionFailed(
-                    callId,
-                    request,
-                    DisconnectCause.ERROR_UNSPECIFIED,
-                    null);
+            createdConnection = Connection.createCanceledConnection();
         }
+        connectionCreated(callId, request, createdConnection);
     }
 
     private void connectionCreated(
             String callId,
             ConnectionRequest request,
             Connection connection) {
-        addConnection(callId, connection);
+        if (!(connection instanceof Connection.FailureSignalingConnection)) {
+            addConnection(callId, connection);
+        }
+
         Uri handle = connection.getHandle();
         String number = handle == null ? "null" : handle.getSchemeSpecificPart();
         Log.v(this, "connectionCreated, parcelableconnection: %s, %d, %s",
@@ -583,7 +528,7 @@
                 PhoneCapabilities.toString(connection.getCallCapabilities()));
 
         Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId);
-        mAdapter.handleCreateConnectionSuccessful(
+        mAdapter.handleCreateConnectionComplete(
                 callId,
                 request,
                 new ParcelableConnection(
@@ -599,7 +544,9 @@
                         connection.getVideoState(),
                         connection.isRequestingRingback(),
                         connection.getAudioModeIsVoip(),
-                        connection.getStatusHints()));
+                        connection.getStatusHints(),
+                        connection.getFailureCode(),
+                        connection.getFailureMessage()));
     }
 
     private void abort(String callId) {
@@ -699,7 +646,8 @@
                     final List<ComponentName> componentNames,
                     final List<IBinder> services) {
                 mHandler.post(new Runnable() {
-                    @Override public void run() {
+                    @Override
+                    public void run() {
                         for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
                             mRemoteConnectionManager.addConnectionService(
                                     componentNames.get(i),
@@ -714,7 +662,8 @@
             @Override
             public void onError() {
                 mHandler.post(new Runnable() {
-                    @Override public void run() {
+                    @Override
+                    public void run() {
                         mAreAccountsInitialized = true;
                     }
                 });
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
index 0188e62..41c6360 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
@@ -76,37 +76,13 @@
         }
     }
 
-    void handleCreateConnectionSuccessful(
+    void handleCreateConnectionComplete(
             String id,
             ConnectionRequest request,
             ParcelableConnection connection) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.handleCreateConnectionSuccessful(id, request, connection);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    void handleCreateConnectionFailed(
-            String id,
-            ConnectionRequest request,
-            int errorCode,
-            String errorMsg) {
-        for (IConnectionServiceAdapter adapter : mAdapters) {
-            try {
-                adapter.handleCreateConnectionFailed(id, request, errorCode, errorMsg);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    void handleCreateConnectionCancelled(
-            String id,
-            ConnectionRequest request) {
-        for (IConnectionServiceAdapter adapter : mAdapters) {
-            try {
-                adapter.handleCreateConnectionCancelled(id, request);
+                adapter.handleCreateConnectionComplete(id, request, connection);
             } catch (RemoteException e) {
             }
         }
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
index 2654ace..0e1c516 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
@@ -38,29 +38,27 @@
  * @hide
  */
 final class ConnectionServiceAdapterServant {
-    private static final int MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL = 1;
-    private static final int MSG_HANDLE_CREATE_CONNECTION_FAILED = 2;
-    private static final int MSG_HANDLE_CREATE_CONNECTION_CANCELLED = 3;
-    private static final int MSG_SET_ACTIVE = 4;
-    private static final int MSG_SET_RINGING = 5;
-    private static final int MSG_SET_DIALING = 6;
-    private static final int MSG_SET_DISCONNECTED = 7;
-    private static final int MSG_SET_ON_HOLD = 8;
-    private static final int MSG_SET_REQUESTING_RINGBACK = 9;
-    private static final int MSG_SET_CALL_CAPABILITIES = 10;
-    private static final int MSG_SET_IS_CONFERENCED = 11;
-    private static final int MSG_ADD_CONFERENCE_CALL = 12;
-    private static final int MSG_REMOVE_CALL = 13;
-    private static final int MSG_ON_POST_DIAL_WAIT = 14;
-    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
-    private static final int MSG_SET_VIDEO_STATE = 16;
-    private static final int MSG_SET_VIDEO_CALL_PROVIDER = 17;
-    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 18;
-    private static final int MSG_SET_STATUS_HINTS = 19;
-    private static final int MSG_SET_HANDLE = 20;
-    private static final int MSG_SET_CALLER_DISPLAY_NAME = 21;
-    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22;
-    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 23;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_COMPLETE = 1;
+    private static final int MSG_SET_ACTIVE = 2;
+    private static final int MSG_SET_RINGING = 3;
+    private static final int MSG_SET_DIALING = 4;
+    private static final int MSG_SET_DISCONNECTED = 5;
+    private static final int MSG_SET_ON_HOLD = 6;
+    private static final int MSG_SET_REQUESTING_RINGBACK = 7;
+    private static final int MSG_SET_CALL_CAPABILITIES = 8;
+    private static final int MSG_SET_IS_CONFERENCED = 9;
+    private static final int MSG_ADD_CONFERENCE_CALL = 10;
+    private static final int MSG_REMOVE_CALL = 11;
+    private static final int MSG_ON_POST_DIAL_WAIT = 12;
+    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13;
+    private static final int MSG_SET_VIDEO_STATE = 14;
+    private static final int MSG_SET_VIDEO_CALL_PROVIDER = 15;
+    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 16;
+    private static final int MSG_SET_STATUS_HINTS = 17;
+    private static final int MSG_SET_HANDLE = 18;
+    private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
+    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 20;
+    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 21;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -76,10 +74,10 @@
         // Internal method defined to centralize handling of RemoteException
         private void internalHandleMessage(Message msg) throws RemoteException {
             switch (msg.what) {
-                case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
+                case MSG_HANDLE_CREATE_CONNECTION_COMPLETE: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.handleCreateConnectionSuccessful(
+                        mDelegate.handleCreateConnectionComplete(
                                 (String) args.arg1,
                                 (ConnectionRequest) args.arg2,
                                 (ParcelableConnection) args.arg3);
@@ -88,30 +86,6 @@
                     }
                     break;
                 }
-                case MSG_HANDLE_CREATE_CONNECTION_FAILED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        mDelegate.handleCreateConnectionFailed(
-                                (String) args.arg1,
-                                (ConnectionRequest) args.arg2,
-                                args.argi1,
-                                (String) args.arg3);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        mDelegate.handleCreateConnectionCancelled(
-                                (String) args.arg1,
-                                (ConnectionRequest) args.arg2);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
                 case MSG_SET_ACTIVE:
                     mDelegate.setActive((String) msg.obj);
                     break;
@@ -244,7 +218,7 @@
 
     private final IConnectionServiceAdapter mStub = new IConnectionServiceAdapter.Stub() {
         @Override
-        public void handleCreateConnectionSuccessful(
+        public void handleCreateConnectionComplete(
                 String id,
                 ConnectionRequest request,
                 ParcelableConnection connection) {
@@ -252,31 +226,7 @@
             args.arg1 = id;
             args.arg2 = request;
             args.arg3 = connection;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
-        }
-
-        @Override
-        public void handleCreateConnectionFailed(
-                String id,
-                ConnectionRequest request,
-                int errorCode,
-                String errorMessage) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = id;
-            args.arg2 = request;
-            args.argi1 = errorCode;
-            args.arg3 = errorMessage;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget();
-        }
-
-        @Override
-        public void handleCreateConnectionCancelled(
-                String id,
-                ConnectionRequest request) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = id;
-            args.arg2 = request;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, args).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
         }
 
         @Override
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index 7a87b87..30ff5be 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -41,6 +41,8 @@
     private boolean mRequestingRingback;
     private boolean mAudioModeIsVoip;
     private StatusHints mStatusHints;
+    private int mFailureCode;
+    private String mFailureMessage;
 
     /** @hide */
     public ParcelableConnection(
@@ -55,7 +57,9 @@
             int videoState,
             boolean requestingRingback,
             boolean audioModeIsVoip,
-            StatusHints statusHints) {
+            StatusHints statusHints,
+            int failureCode,
+            String failureMessage) {
         mPhoneAccount = phoneAccount;
         mState = state;
         mCapabilities = capabilities;
@@ -68,6 +72,8 @@
         mRequestingRingback = requestingRingback;
         mAudioModeIsVoip = audioModeIsVoip;
         mStatusHints = statusHints;
+        mFailureCode = failureCode;
+        mFailureMessage = failureMessage;
     }
 
     public PhoneAccountHandle getPhoneAccount() {
@@ -119,6 +125,14 @@
         return mStatusHints;
     }
 
+    public final int getFailureCode() {
+        return mFailureCode;
+    }
+
+    public final String getFailureMessage() {
+        return mFailureMessage;
+    }
+
     @Override
     public String toString() {
         return new StringBuilder()
@@ -150,6 +164,8 @@
             boolean requestingRingback = source.readByte() == 1;
             boolean audioModeIsVoip = source.readByte() == 1;
             StatusHints statusHints = source.readParcelable(classLoader);
+            int disconnectCauseCode = source.readInt();
+            String disconnectCauseMessage = source.readString();
 
             return new ParcelableConnection(
                     phoneAccount,
@@ -163,7 +179,9 @@
                     videoState,
                     requestingRingback,
                     audioModeIsVoip,
-                    statusHints);
+                    statusHints,
+                    disconnectCauseCode,
+                    disconnectCauseMessage);
         }
 
         @Override
@@ -194,5 +212,7 @@
         destination.writeByte((byte) (mRequestingRingback ? 1 : 0));
         destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0));
         destination.writeParcelable(mStatusHints, 0);
+        destination.writeInt(mFailureCode);
+        destination.writeString(mFailureMessage);
     }
 }
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
index f1cee10..30cfdde 100644
--- a/telecomm/java/android/telecomm/RemoteConnection.java
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -233,9 +233,9 @@
     RemoteConnection(int failureCode, String failureMessage) {
         this("NULL", null, null);
         mConnected = false;
-        mState = Connection.STATE_FAILED;
-        mFailureCode = failureCode;
-        mFailureMessage = failureMessage;
+        mState = Connection.STATE_DISCONNECTED;
+        mFailureCode = DisconnectCause.OUTGOING_FAILURE;
+        mFailureMessage = failureMessage + " original code = " + failureCode;
     }
 
     /**
@@ -675,8 +675,9 @@
     }
 
     /**
-     * Create a RemoteConnection which is in the {@link Connection#STATE_FAILED} state. Attempting
-     * to use it for anything will almost certainly result in bad things happening. Do not do this.
+     * Create a RemoteConnection represents a failure, and which will be in
+     * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
+     * certainly result in bad things happening. Do not do this.
      *
      * @return a failed {@link RemoteConnection}
      *
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index dedb10e..541df4e 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -48,7 +48,7 @@
 
     private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
         @Override
-        public void handleCreateConnectionSuccessful(
+        public void handleCreateConnectionComplete(
                 String id,
                 ConnectionRequest request,
                 ParcelableConnection parcel) {
@@ -56,6 +56,7 @@
                     findConnectionForAction(id, "handleCreateConnectionSuccessful");
             if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
                 mPendingConnections.remove(connection);
+                // Unconditionally initialize the connection ...
                 connection.setState(parcel.getState());
                 connection.setCallCapabilities(parcel.getCapabilities());
                 connection.setHandle(
@@ -64,29 +65,15 @@
                         parcel.getCallerDisplayName(),
                         parcel.getCallerDisplayNamePresentation());
                 // TODO: Do we need to support video providers for remote connections?
+                if (connection.getState() == Connection.STATE_DISCONNECTED) {
+                    // ... then, if it was created in a disconnected state, that indicates
+                    // failure on the providing end, so immediately mark it destroyed
+                    connection.setDestroyed();
+                }
             }
         }
 
         @Override
-        public void handleCreateConnectionFailed(
-                String id,
-                ConnectionRequest request,
-                int errorCode,
-                String errorMessage) {
-            // TODO: How do we propagate the failure codes?
-            findConnectionForAction(id, "handleCreateConnectionFailed")
-                    .setDestroyed();
-        }
-
-        @Override
-        public void handleCreateConnectionCancelled(
-                String id,
-                ConnectionRequest request) {
-            findConnectionForAction(id, "handleCreateConnectionCancelled")
-                    .setDestroyed();
-        }
-
-        @Override
         public void setActive(String callId) {
             findConnectionForAction(callId, "setActive")
                     .setState(Connection.STATE_ACTIVE);
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
index e6ebae5..ef1769f 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
@@ -34,20 +34,11 @@
  * {@hide}
  */
 oneway interface IConnectionServiceAdapter {
-    void handleCreateConnectionSuccessful(
+    void handleCreateConnectionComplete(
             String callId,
             in ConnectionRequest request,
             in ParcelableConnection connection);
 
-    void handleCreateConnectionFailed(
-            String callId,
-            in ConnectionRequest request,
-            int errorCode, String errorMessage);
-
-    void handleCreateConnectionCancelled(
-            String callId,
-            in ConnectionRequest request);
-
     void setActive(String callId);
 
     void setRinging(String callId);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c50110a..d4f8362 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2459,7 +2459,7 @@
      * @param filePath
      * @return The APDU response.
      */
-    byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
+    public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
             String filePath) {
         try {
             return getITelephony().iccExchangeSimIO(fileID, command, p1, p2,
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index cf1d4fd..c98808f 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -484,15 +484,6 @@
                 attr.hasErrors = true;
             }
 
-            // Make sure an id is defined for this enum/flag identifier...
-            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
-                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
-                                         myPackage, id16, itemIdent, String16(), NULL);
-                if (err != NO_ERROR) {
-                    attr.hasErrors = true;
-                }
-            }
-
             if (!attr.hasErrors) {
                 if (enumOrFlagsComment.size() == 0) {
                     enumOrFlagsComment.append(mayOrMust(attr.type,
@@ -2508,11 +2499,13 @@
         sp<Type> attr = p->getType(String16("attr"), unknown);
 
         // Assign indices...
-        for (ti=0; ti<N; ti++) {
+        const size_t typeCount = p->getOrderedTypes().size();
+        for (size_t ti = 0; ti < typeCount; ti++) {
             sp<Type> t = p->getOrderedTypes().itemAt(ti);
             if (t == NULL) {
                 continue;
             }
+
             err = t->applyPublicEntryOrder();
             if (err != NO_ERROR && firstError == NO_ERROR) {
                 firstError = err;
@@ -2534,7 +2527,7 @@
         }
 
         // Assign resource IDs to keys in bags...
-        for (ti=0; ti<N; ti++) {
+        for (size_t ti = 0; ti < typeCount; ti++) {
             sp<Type> t = p->getOrderedTypes().itemAt(ti);
             if (t == NULL) {
                 continue;
@@ -3296,11 +3289,16 @@
     Item item(sourcePos, false, value, style);
 
     if (mType == TYPE_BAG) {
-        const Item& item(mBag.valueAt(0));
-        sourcePos.error("Resource entry %s is already defined as a bag.\n"
-                        "%s:%d: Originally defined here.\n",
-                        String8(mName).string(),
-                        item.sourcePos.file.string(), item.sourcePos.line);
+        if (mBag.size() == 0) {
+            sourcePos.error("Resource entry %s is already defined as a bag.",
+                    String8(mName).string());
+        } else {
+            const Item& item(mBag.valueAt(0));
+            sourcePos.error("Resource entry %s is already defined as a bag.\n"
+                            "%s:%d: Originally defined here.\n",
+                            String8(mName).string(),
+                            item.sourcePos.file.string(), item.sourcePos.line);
+        }
         return UNKNOWN_ERROR;
     }
     if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
@@ -3374,6 +3372,9 @@
         if (it.isId) {
             if (!table->hasBagOrEntry(key, &id16, &package)) {
                 String16 value("false");
+                NOISY(fprintf(stderr, "Generating %s:id/%s\n",
+                        String8(package).string(),
+                        String8(key).string()));
                 status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
                                                id16, key, value);
                 if (err != NO_ERROR) {
diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
index 75bfb6e..04571e1 100644
--- a/tools/layoutlib/bridge/resources/bars/status_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/status_bar.xml
@@ -1,17 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_marginTop="1dp"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_marginLeft="3dp"
-			android:layout_marginRight="5dp"
-			android:layout_marginTop="2dp"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"/>
+    <!-- The exact size of the wifi icon is specified in order to scale it properly.
+    Without scaling, it appeared huge. This is currently, 70% of the actual size. -->
+    <ImageView
+            android:layout_height="22.4dp"
+            android:layout_width="20.65dp"
+            android:layout_marginTop="1dp"/>
+    <ImageView
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginLeft="3dp"
+            android:layout_marginRight="5dp"
+            android:layout_marginTop="4dp"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:layout_marginRight="5dp"
+            android:gravity="center_vertical"
+            android:textSize="16dp"
+            android:fontFamily="sans-serif-medium"/>
 </merge>
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 931daed..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6e1ac91..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 625c61d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
new file mode 100644
index 0000000..0498b6c
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="29.5dp"
+        android:viewportWidth="26.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+</vector>
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index f939678..5b69681 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -91,7 +91,7 @@
         // first count the array size
         int count = 0;
         for (ResourceValue data : mResourceData) {
-            if (data != null) {
+            if (data != null && !RenderResources.REFERENCE_NULL.equals(data.getValue())) {
                 count++;
             }
         }
@@ -103,7 +103,8 @@
         // fill the array with the indices.
         int index = 1;
         for (int i = 0 ; i < mResourceData.length ; i++) {
-            if (mResourceData[i] != null) {
+            if (mResourceData[i] != null
+                    && !RenderResources.REFERENCE_NULL.equals(mResourceData[i].getValue())) {
                 mIndices[index++] = i;
             }
         }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 9b814f5..16b54f1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -20,10 +20,7 @@
 import java.util.Collections;
 import java.util.List;
 
-import static android.os.Build.VERSION_CODES.GINGERBREAD;
-import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
-import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
-import static android.os.Build.VERSION_CODES.KITKAT;
+import static android.os.Build.VERSION_CODES.*;
 
 /**
  * Various helper methods to simulate older versions of platform.
@@ -39,13 +36,16 @@
     private static final List<String> sDefaultResourceDir =
             Collections.singletonList(DEFAULT_RESOURCE_DIR);
 
+    private static final int WHITE = 0xFFFFFFFF;
+    private static final int BLACK = 0xFF000000;
+
     public static boolean showOnScreenNavBar(int platformVersion) {
         return platformVersion == 0 || platformVersion >= ICE_CREAM_SANDWICH;
     }
 
     public static int getStatusBarColor(int platformVersion) {
         // return white for froyo and earlier; black otherwise.
-        return platformVersion == 0 || platformVersion >= GINGERBREAD ? 0xFF000000 : 0xFFFFFFFF;
+        return platformVersion == 0 || platformVersion >= GINGERBREAD ? BLACK : WHITE;
     }
 
     public static List<String> getResourceDirs(int platformVersion) {
@@ -70,4 +70,49 @@
 
         return Collections.unmodifiableList(list);
     }
+
+    public static String getTime(int platformVersion) {
+        if (platformVersion == 0) {
+            // TODO: revisit when the version is selected.
+            return "4:57";
+        }
+        if (platformVersion < GINGERBREAD) {
+            return "2:20";
+        }
+        if (platformVersion < ICE_CREAM_SANDWICH) {
+            return "2:30";
+        }
+        if (platformVersion < JELLY_BEAN) {
+            return "4:00";
+        }
+        if (platformVersion < KITKAT) {
+            return "4:30";
+        }
+        if (platformVersion <= KITKAT_WATCH) {
+            return "4:40";
+        }
+        // Should never happen.
+        return "4:04";
+    }
+
+    public static int getTimeColor(int platformVersion) {
+        if (platformVersion == 0 || platformVersion >= KITKAT ||
+                platformVersion > FROYO && platformVersion < HONEYCOMB) {
+            // Gingerbread and KitKat onwards.
+            return WHITE;
+        }
+        // Black for froyo.
+        if (platformVersion < GINGERBREAD) {
+            return BLACK;
+        } else if (platformVersion < KITKAT) {
+            // Honeycomb to JB-mr2: Holo blue light.
+            return 0xff33b5e5;
+        }
+        // Should never happen.
+        return WHITE;
+    }
+
+    public static String getWifiIconType(int platformVersion) {
+        return platformVersion == 0 ? "xml" : "png";
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index bed232ab..13ddf07 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -127,24 +127,25 @@
         }
     }
 
-    protected TextView setText(int index, String stringReference) {
+    protected TextView setText(int index, String string, boolean reference) {
         View child = getChildAt(index);
         if (child instanceof TextView) {
             TextView textView = (TextView) child;
-            setText(textView, stringReference);
+            setText(textView, string, reference);
             return textView;
         }
 
         return null;
     }
 
-    private void setText(TextView textView, String stringReference) {
-        ResourceValue value = getResourceValue(stringReference);
-        if (value != null) {
-            textView.setText(value.getValue());
-        } else {
-            textView.setText(stringReference);
+    private void setText(TextView textView, String string, boolean reference) {
+        if (reference) {
+            ResourceValue value = getResourceValue(string);
+            if (value != null) {
+                string = value.getValue();
+            }
         }
+        textView.setText(string);
     }
 
     protected void setStyle(String themeEntryName) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 1795db9..c7c62d6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -16,22 +16,38 @@
 
 package com.android.layoutlib.bridge.bars;
 
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.resources.Density;
 
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.view.Gravity;
+import android.view.View;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import java.io.IOException;
+import java.io.InputStream;
+
 public class StatusBar extends CustomBar {
 
+    private final Context mContext;
+    private final int mSimulatedPlatformVersion;
+
     public StatusBar(Context context, Density density, int direction, boolean RtlEnabled,
             int simulatedPlatformVersion) throws XmlPullParserException {
         // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
         super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml",
                 simulatedPlatformVersion);
+        mContext = context;
+        mSimulatedPlatformVersion = simulatedPlatformVersion;
 
         // FIXME: use FILL_H?
         setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
@@ -41,8 +57,44 @@
         // created for them.
         // We do know the order though.
         // 0 is the spacer
-        loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density);
+        loadIcon(1, "stat_sys_wifi_signal_4_fully."
+                        + Config.getWifiIconType(simulatedPlatformVersion), density);
         loadIcon(2, "stat_sys_battery_100.png", density);
+        setText(3, Config.getTime(simulatedPlatformVersion), false)
+                .setTextColor(Config.getTimeColor(simulatedPlatformVersion));
+    }
+
+    @Override
+    protected void loadIcon(int index, String iconName, Density density) {
+        if (!iconName.endsWith(".xml")) {
+            super.loadIcon(index, iconName, density);
+            return;
+        }
+        View child = getChildAt(index);
+        if (child instanceof ImageView) {
+            ImageView imageView = (ImageView) child;
+            // The xml is stored only in xhdpi.
+            IconLoader iconLoader = new IconLoader(iconName, Density.XHIGH,
+                    mSimulatedPlatformVersion, null);
+            InputStream stream = iconLoader.getIcon();
+
+            if (stream != null) {
+                try {
+                    BridgeXmlBlockParser parser = new BridgeXmlBlockParser(
+                            ParserFactory.create(stream, null), (BridgeContext) mContext, true);
+                    Drawable drawable = Drawable.createFromXml(mContext.getResources(), parser);
+                    if (drawable != null) {
+                        imageView.setImageDrawable(drawable);
+                    }
+                } catch (XmlPullParserException e) {
+                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
+                            null);
+                } catch (IOException e) {
+                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
+                            null);
+                }
+            }
+        }
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
index ff952bd..10f1383 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -34,7 +34,7 @@
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
         // We do know the order though.
-        mTextView = setText(0, label);
+        mTextView = setText(0, label, true);
 
         setStyle("windowTitleBackgroundStyle");
     }
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 3c37b94..ac2a176 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -21,7 +21,7 @@
 import android.net.IpConfiguration.ProxySettings;
 import android.net.IpConfiguration.IpAssignment;
 import android.net.ProxyInfo;
-import android.net.LinkProperties;
+import android.net.StaticIpConfiguration;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -1096,13 +1096,13 @@
     }
 
     /** @hide */
-    public LinkProperties getLinkProperties() {
-        return mIpConfiguration.linkProperties;
+    public StaticIpConfiguration getStaticIpConfiguration() {
+        return mIpConfiguration.getStaticIpConfiguration();
     }
 
     /** @hide */
-    public void setLinkProperties(LinkProperties linkProperties) {
-        mIpConfiguration.linkProperties = linkProperties;
+    public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
+        mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration);
     }
 
     /** @hide */
@@ -1126,9 +1126,19 @@
     }
 
     /** @hide */
+    public ProxyInfo getHttpProxy() {
+        return mIpConfiguration.httpProxy;
+    }
+
+    /** @hide */
+    public void setHttpProxy(ProxyInfo httpProxy) {
+        mIpConfiguration.httpProxy = httpProxy;
+    }
+
+    /** @hide */
     public void setProxy(ProxySettings settings, ProxyInfo proxy) {
         mIpConfiguration.proxySettings = settings;
-        mIpConfiguration.linkProperties.setHttpProxy(proxy);
+        mIpConfiguration.httpProxy = proxy;
     }
 
     /** Implement the Parcelable interface {@hide} */