Merge "Reverting changes to the accessibility layer."
diff --git a/Android.mk b/Android.mk
index 57091cc..5c48dfe 100644
--- a/Android.mk
+++ b/Android.mk
@@ -162,6 +162,7 @@
 	core/java/android/os/ICancellationSignal.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
+	core/java/android/os/INetworkActivityListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
 	core/java/android/os/IPermissionController.aidl \
 	core/java/android/os/IPowerManager.aidl \
@@ -261,23 +262,23 @@
 	media/java/android/media/IAudioService.aidl \
 	media/java/android/media/IAudioFocusDispatcher.aidl \
 	media/java/android/media/IAudioRoutesObserver.aidl \
-	media/java/android/media/IMediaController.aidl \
-	media/java/android/media/IMediaControllerCallback.aidl \
 	media/java/android/media/IMediaHTTPConnection.aidl \
 	media/java/android/media/IMediaHTTPService.aidl \
 	media/java/android/media/IMediaRouterClient.aidl \
 	media/java/android/media/IMediaRouterService.aidl \
 	media/java/android/media/IMediaScannerListener.aidl \
 	media/java/android/media/IMediaScannerService.aidl \
-	media/java/android/media/IMediaSession.aidl \
-	media/java/android/media/IMediaSessionCallback.aidl \
-	media/java/android/media/IMediaSessionManager.aidl \
 	media/java/android/media/IRemoteControlClient.aidl \
 	media/java/android/media/IRemoteControlDisplay.aidl \
 	media/java/android/media/IRemoteDisplayCallback.aidl \
 	media/java/android/media/IRemoteDisplayProvider.aidl \
 	media/java/android/media/IRemoteVolumeObserver.aidl \
 	media/java/android/media/IRingtonePlayer.aidl \
+	media/java/android/media/session/IMediaController.aidl \
+	media/java/android/media/session/IMediaControllerCallback.aidl \
+	media/java/android/media/session/IMediaSession.aidl \
+	media/java/android/media/session/IMediaSessionCallback.aidl \
+	media/java/android/media/session/IMediaSessionManager.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1e49fcb..448b03d 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -186,6 +186,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrintClient.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java/android/media/IMedia*)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/current.txt b/api/current.txt
index eb39a16..6655734 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -345,7 +345,7 @@
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
     field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
     field public static final deprecated int capitalize = 16843113; // 0x1010169
-    field public static final int castsShadow = 16843777; // 0x1010401
+    field public static final int castsShadow = 16843775; // 0x10103ff
     field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
     field public static final int centerColor = 16843275; // 0x101020b
@@ -542,7 +542,6 @@
     field public static final int fromAlpha = 16843210; // 0x10101ca
     field public static final int fromDegrees = 16843187; // 0x10101b3
     field public static final int fromScene = 16843741; // 0x10103dd
-    field public static final int fromSceneName = 16843773; // 0x10103fd
     field public static final int fromXDelta = 16843206; // 0x10101c6
     field public static final int fromXScale = 16843202; // 0x10101c2
     field public static final int fromYDelta = 16843208; // 0x10101c8
@@ -890,6 +889,7 @@
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
+    field public static final int requiredForProfile = 16843776; // 0x1010400
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeMode = 16843619; // 0x1010363
@@ -960,7 +960,7 @@
     field public static final int shadowRadius = 16843108; // 0x1010164
     field public static final int shape = 16843162; // 0x101019a
     field public static final int shareInterpolator = 16843195; // 0x10101bb
-    field public static final int sharedElementName = 16843775; // 0x10103ff
+    field public static final int sharedElementName = 16843773; // 0x10103fd
     field public static final int sharedUserId = 16842763; // 0x101000b
     field public static final int sharedUserLabel = 16843361; // 0x1010261
     field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1144,7 +1144,6 @@
     field public static final int toAlpha = 16843211; // 0x10101cb
     field public static final int toDegrees = 16843188; // 0x10101b4
     field public static final int toScene = 16843742; // 0x10103de
-    field public static final int toSceneName = 16843774; // 0x10103fe
     field public static final int toXDelta = 16843207; // 0x10101c7
     field public static final int toXScale = 16843203; // 0x10101c3
     field public static final int toYDelta = 16843209; // 0x10101c9
@@ -1160,7 +1159,7 @@
     field public static final int transformPivotX = 16843552; // 0x1010320
     field public static final int transformPivotY = 16843553; // 0x1010321
     field public static final int transition = 16843743; // 0x10103df
-    field public static final int transitionGroup = 16843776; // 0x1010400
+    field public static final int transitionGroup = 16843774; // 0x10103fe
     field public static final int transitionOrdering = 16843744; // 0x10103e0
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
@@ -3040,7 +3039,6 @@
     method public int getTaskId();
     method public final java.lang.CharSequence getTitle();
     method public final int getTitleColor();
-    method public android.os.Bundle getTransitionArgs();
     method public final int getVolumeControlStream();
     method public android.view.Window getWindow();
     method public android.view.WindowManager getWindowManager();
@@ -3062,6 +3060,8 @@
     method public void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
     method public void onBackPressed();
+    method public void onCaptureSharedElementEnd();
+    method public void onCaptureSharedElementStart(android.transition.Transition);
     method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence);
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public void onContentChanged();
@@ -3136,7 +3136,6 @@
     method public void setContentView(android.view.View);
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public final void setDefaultKeyMode(int);
-    method public void setEarlyBackgroundTransition(boolean);
     method public final void setFeatureDrawable(int, android.graphics.drawable.Drawable);
     method public final void setFeatureDrawableAlpha(int, int);
     method public final void setFeatureDrawableResource(int, int);
@@ -3177,7 +3176,6 @@
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
-    method protected void startSharedElementTransition(android.os.Bundle);
     method public deprecated void stopManagingCursor(android.database.Cursor);
     method public void takeKeyEvents(boolean);
     method public void triggerSearch(java.lang.String, android.os.Bundle);
@@ -3348,23 +3346,13 @@
   public class ActivityOptions {
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
     method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
-    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.os.Bundle);
+    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.view.View, java.lang.String);
+    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.util.Pair<android.view.View, java.lang.String>...);
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
   }
 
-  public class ActivityView extends android.view.ViewGroup {
-    ctor public ActivityView(android.content.Context);
-    ctor public ActivityView(android.content.Context, android.util.AttributeSet);
-    ctor public ActivityView(android.content.Context, android.util.AttributeSet, int);
-    method public boolean isAttachedToDisplay();
-    method protected void onLayout(boolean, int, int, int, int);
-    method public void startActivity(android.content.Intent);
-    method public void startActivity(android.content.IntentSender);
-    method public void startActivity(android.app.PendingIntent);
-  }
-
   public class AlarmManager {
     method public void cancel(android.app.PendingIntent);
     method public void set(int, long, android.app.PendingIntent);
@@ -10397,6 +10385,7 @@
     method public final android.graphics.Paint getPaint();
     method public android.graphics.Shader.TileMode getTileModeX();
     method public android.graphics.Shader.TileMode getTileModeY();
+    method public android.content.res.ColorStateList getTint();
     method public boolean hasAntiAlias();
     method public boolean hasMipMap();
     method public final boolean isAutoMirrored();
@@ -10412,7 +10401,6 @@
     method public void setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
     method public final void setTileModeY(android.graphics.Shader.TileMode);
     method public void setTint(android.content.res.ColorStateList);
-    method public void setTintMode(android.graphics.PorterDuff.Mode);
   }
 
   public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -10455,6 +10443,7 @@
     method public final android.graphics.Rect getBounds();
     method public android.graphics.drawable.Drawable.Callback getCallback();
     method public int getChangingConfigurations();
+    method public android.graphics.ColorFilter getColorFilter();
     method public android.graphics.drawable.Drawable.ConstantState getConstantState();
     method public android.graphics.drawable.Drawable getCurrent();
     method public int getIntrinsicHeight();
@@ -10643,13 +10632,13 @@
     method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.Paint getPaint();
+    method public android.content.res.ColorStateList getTint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
     method public void setTint(android.content.res.ColorStateList);
-    method public void setTintMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PaintDrawable extends android.graphics.drawable.ShapeDrawable {
@@ -10718,6 +10707,7 @@
     method public android.graphics.Paint getPaint();
     method public android.graphics.drawable.ShapeDrawable.ShaderFactory getShaderFactory();
     method public android.graphics.drawable.shapes.Shape getShape();
+    method public android.content.res.ColorStateList getTint();
     method protected boolean inflateTag(java.lang.String, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet);
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
@@ -10728,6 +10718,7 @@
     method public void setPadding(android.graphics.Rect);
     method public void setShaderFactory(android.graphics.drawable.ShapeDrawable.ShaderFactory);
     method public void setShape(android.graphics.drawable.shapes.Shape);
+    method public void setTint(android.content.res.ColorStateList);
   }
 
   public static abstract class ShapeDrawable.ShaderFactory {
@@ -11835,6 +11826,20 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public class UsbConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAttributes();
+    method public int getId();
+    method public android.hardware.usb.UsbInterface getInterface(int);
+    method public int getInterfaceCount();
+    method public int getMaxPower();
+    method public java.lang.String getName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ATTR_REMOTE_WAKEUP_MASK = 32; // 0x20
+    field public static final int ATTR_SELF_POWERED_MASK = 64; // 0x40
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public final class UsbConstants {
     ctor public UsbConstants();
     field public static final int USB_CLASS_APP_SPEC = 254; // 0xfe
@@ -11874,6 +11879,8 @@
 
   public class UsbDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public android.hardware.usb.UsbConfiguration getConfiguration(int);
+    method public int getConfigurationCount();
     method public int getDeviceClass();
     method public int getDeviceId();
     method public static int getDeviceId(java.lang.String);
@@ -11904,6 +11911,8 @@
     method public java.lang.String getSerial();
     method public boolean releaseInterface(android.hardware.usb.UsbInterface);
     method public android.hardware.usb.UsbRequest requestWait();
+    method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
+    method public boolean setInterface(android.hardware.usb.UsbInterface);
   }
 
   public class UsbEndpoint implements android.os.Parcelable {
@@ -11921,12 +11930,14 @@
 
   public class UsbInterface implements android.os.Parcelable {
     method public int describeContents();
+    method public int getAlternateSetting();
     method public android.hardware.usb.UsbEndpoint getEndpoint(int);
     method public int getEndpointCount();
     method public int getId();
     method public int getInterfaceClass();
     method public int getInterfaceProtocol();
     method public int getInterfaceSubclass();
+    method public java.lang.String getName();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -12482,7 +12493,7 @@
     ctor public SettingInjectorService(java.lang.String);
     method public final android.os.IBinder onBind(android.content.Intent);
     method protected abstract boolean onGetEnabled();
-    method protected abstract java.lang.String onGetSummary();
+    method protected deprecated java.lang.String onGetSummary();
     method public final void onStart(android.content.Intent, int);
     method public final int onStartCommand(android.content.Intent, int, int);
     field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
@@ -13184,23 +13195,6 @@
     method public static final android.media.MediaCodecInfo getCodecInfoAt(int);
   }
 
-  public final class MediaController {
-    ctor public MediaController(android.media.MediaSessionToken);
-    method public void addCallback(android.media.MediaController.Callback);
-    method public void addCallback(android.media.MediaController.Callback, android.os.Handler);
-    method public void removeCallback(android.media.MediaController.Callback);
-    method public void sendCommand(java.lang.String, android.os.Bundle);
-    method public void sendMediaButton(int);
-  }
-
-  public static abstract class MediaController.Callback {
-    ctor public MediaController.Callback();
-    method public void onEvent(java.lang.String, android.os.Bundle);
-    method public void onMetadataUpdate(android.os.Bundle);
-    method public void onPlaybackStateChange(int);
-    method public void onRouteChanged(android.os.Bundle);
-  }
-
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
@@ -13767,33 +13761,6 @@
     method public abstract void onScanCompleted(java.lang.String, android.net.Uri);
   }
 
-  public final class MediaSession {
-    method public void addCallback(android.media.MediaSession.Callback);
-    method public void addCallback(android.media.MediaSession.Callback, android.os.Handler);
-    method public android.media.MediaSessionToken getSessionToken();
-    method public void release();
-    method public void removeCallback(android.media.MediaSession.Callback);
-    method public void setPlaybackState(int);
-  }
-
-  public static abstract class MediaSession.Callback {
-    ctor public MediaSession.Callback();
-    method public void onCommand(java.lang.String, android.os.Bundle);
-    method public void onMediaButton(android.content.Intent);
-    method public void onRequestRouteChange(android.os.Bundle);
-  }
-
-  public final class MediaSessionManager {
-    method public android.media.MediaSession createSession(java.lang.String);
-    method public java.util.List<android.media.MediaController> getActiveSessions();
-  }
-
-  public class MediaSessionToken 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 class MediaSyncEvent {
     method public static android.media.MediaSyncEvent createEvent(int) throws java.lang.IllegalArgumentException;
     method public int getAudioSessionId();
@@ -14463,6 +14430,54 @@
 
 }
 
+package android.media.session {
+
+  public final class MediaController {
+    ctor public MediaController(android.media.session.MediaSessionToken);
+    method public void addCallback(android.media.session.MediaController.Callback);
+    method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public void removeCallback(android.media.session.MediaController.Callback);
+    method public void sendCommand(java.lang.String, android.os.Bundle);
+    method public void sendMediaButton(int);
+  }
+
+  public static abstract class MediaController.Callback {
+    ctor public MediaController.Callback();
+    method public void onEvent(java.lang.String, android.os.Bundle);
+    method public void onMetadataUpdate(android.os.Bundle);
+    method public void onPlaybackStateChange(int);
+    method public void onRouteChanged(android.os.Bundle);
+  }
+
+  public final class MediaSession {
+    method public void addCallback(android.media.session.MediaSession.Callback);
+    method public void addCallback(android.media.session.MediaSession.Callback, android.os.Handler);
+    method public android.media.session.MediaSessionToken getSessionToken();
+    method public void release();
+    method public void removeCallback(android.media.session.MediaSession.Callback);
+    method public void setPlaybackState(int);
+  }
+
+  public static abstract class MediaSession.Callback {
+    ctor public MediaSession.Callback();
+    method public void onCommand(java.lang.String, android.os.Bundle);
+    method public void onMediaButton(android.content.Intent);
+    method public void onRequestRouteChange(android.os.Bundle);
+  }
+
+  public final class MediaSessionManager {
+    method public android.media.session.MediaSession createSession(java.lang.String);
+    method public java.util.List<android.media.session.MediaController> getActiveSessions();
+  }
+
+  public class MediaSessionToken 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;
+  }
+
+}
+
 package android.mtp {
 
   public final class MtpConstants {
@@ -14599,11 +14614,14 @@
     method public android.net.NetworkInfo getNetworkInfo(int);
     method public int getNetworkPreference();
     method public boolean isActiveNetworkMetered();
+    method public boolean isNetworkActive();
     method public static boolean isNetworkTypeValid(int);
+    method public void registerNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
     method public boolean requestRouteToHost(int, int);
     method public void setNetworkPreference(int);
     method public int startUsingNetworkFeature(int, java.lang.String);
     method public int stopUsingNetworkFeature(int, java.lang.String);
+    method public void unregisterNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
     field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
     field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
     field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
@@ -14626,6 +14644,10 @@
     field public static final int TYPE_WIMAX = 6; // 0x6
   }
 
+  public static abstract interface ConnectivityManager.OnNetworkActiveListener {
+    method public abstract void onNetworkActive();
+  }
+
   public class Credentials {
     ctor public Credentials(int, int, int);
     method public int getGid();
@@ -15522,6 +15544,7 @@
     method public int describeContents();
     method public java.lang.String getBSSID();
     method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
+    method public int getFrequency();
     method public boolean getHiddenSSID();
     method public int getIpAddress();
     method public int getLinkSpeed();
@@ -15531,6 +15554,7 @@
     method public java.lang.String getSSID();
     method public android.net.wifi.SupplicantState getSupplicantState();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String FREQUENCY_UNITS = "MHz";
     field public static final java.lang.String LINK_SPEED_UNITS = "Mbps";
   }
 
@@ -15843,6 +15867,7 @@
     method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String);
     method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]);
     method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]);
+    method public static android.nfc.NdefRecord createTextRecord(java.lang.String, java.lang.String);
     method public static android.nfc.NdefRecord createUri(android.net.Uri);
     method public static android.nfc.NdefRecord createUri(java.lang.String);
     method public int describeContents();
@@ -15879,6 +15904,7 @@
     method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
     method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
+    method public boolean invokeBeam(android.app.Activity);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
     method public void setBeamPushUris(android.net.Uri[], android.app.Activity);
@@ -16309,8 +16335,10 @@
   }
 
   public abstract class EGLObjectHandle {
-    ctor protected EGLObjectHandle(int);
-    method public int getHandle();
+    ctor protected deprecated EGLObjectHandle(int);
+    ctor protected EGLObjectHandle(long);
+    method public deprecated int getHandle();
+    method public long getNativeHandle();
   }
 
   public class EGLSurface extends android.opengl.EGLObjectHandle {
@@ -26828,15 +26856,11 @@
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
     method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition);
-    method public android.transition.Transition getNamedTransition(java.lang.String, android.transition.Scene);
-    method public android.transition.Transition getNamedTransition(android.transition.Scene, java.lang.String);
-    method public java.lang.String[] getTargetSceneNames(android.transition.Scene);
     method public static void go(android.transition.Scene);
     method public static void go(android.transition.Scene, android.transition.Transition);
+    method public void setExitTransition(android.transition.Scene, android.transition.Transition);
     method public void setTransition(android.transition.Scene, android.transition.Transition);
     method public void setTransition(android.transition.Scene, android.transition.Scene, android.transition.Transition);
-    method public void setTransition(android.transition.Scene, java.lang.String, android.transition.Transition);
-    method public void setTransition(java.lang.String, android.transition.Scene, android.transition.Transition);
     method public void transitionTo(android.transition.Scene);
   }
 
@@ -29807,6 +29831,7 @@
     method public abstract boolean isFloating();
     method public abstract boolean isShortcutKey(int, android.view.KeyEvent);
     method public final void makeActive();
+    method public void mapTransitionTargets(java.util.Map<java.lang.String, java.lang.String>);
     method protected abstract void onActive();
     method public abstract void onConfigurationChanged(android.content.res.Configuration);
     method public abstract void openPanel(int, android.view.KeyEvent);
@@ -29845,6 +29870,7 @@
     method public abstract void setTitle(java.lang.CharSequence);
     method public abstract deprecated void setTitleColor(int);
     method public void setTransitionManager(android.transition.TransitionManager);
+    method public void setTriggerEarlyEnterTransition(boolean);
     method public void setType(int);
     method public void setUiOptions(int);
     method public void setUiOptions(int, int);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 89e15d2..01e7615 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -232,6 +232,8 @@
                 "    [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
                 "    [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
                 "    [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
+                "    [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" +
+                "        (to embed a comma into a string escape it using \"\\,\")\n" +
                 "    [-n <COMPONENT>] [-f <FLAGS>]\n" +
                 "    [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
                 "    [--debug-log-resolution] [--exclude-stopped-packages]\n" +
@@ -419,6 +421,15 @@
                 }
                 intent.putExtra(key, list);
                 hasIntentInfo = true;
+            } else if (opt.equals("--esa")) {
+                String key = nextArgRequired();
+                String value = nextArgRequired();
+                // Split on commas unless they are preceeded by an escape.
+                // The escape character must be escaped for the string and
+                // again for the regex, thus four escape characters become one.
+                String[] strings = value.split("(?<!\\\\),");
+                intent.putExtra(key, strings);
+                hasIntentInfo = true;
             } else if (opt.equals("--ez")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index d5ff84e..a4e2718 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -19,9 +19,6 @@
     libGLESv1_CM \
     libgui
 
-LOCAL_C_INCLUDES := \
-	$(call include-path-for, corecg graphics)
-
 LOCAL_MODULE:= bootanimation
 
 
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 125bea6..e12e961 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -42,9 +42,9 @@
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 
-#include <core/SkBitmap.h>
-#include <core/SkStream.h>
-#include <core/SkImageDecoder.h>
+#include <SkBitmap.h>
+#include <SkStream.h>
+#include <SkImageDecoder.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
diff --git a/cmds/screencap/Android.mk b/cmds/screencap/Android.mk
index ca8008b..5c11b75 100644
--- a/cmds/screencap/Android.mk
+++ b/cmds/screencap/Android.mk
@@ -16,11 +16,4 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_C_INCLUDES += \
-	external/skia/include/core \
-	external/skia/include/effects \
-	external/skia/include/images \
-	external/skia/src/ports \
-	external/skia/include/utils
-
 include $(BUILD_EXECUTABLE)
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4f0683c..3297fe0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.transition.Scene;
+import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.util.ArrayMap;
 import android.util.SuperNotCalledException;
@@ -1030,7 +1031,7 @@
     /**
      * Called after {@link #onCreate} &mdash; or after {@link #onRestart} when  
      * the activity had been stopped, but is now again being displayed to the 
-	 * user.  It will be followed by {@link #onResume}.
+     * user.  It will be followed by {@link #onResume}.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
@@ -3316,7 +3317,7 @@
             @Nullable Bundle appSearchData, boolean globalSearch) {
         ensureSearchManager();
         mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
-                        appSearchData, globalSearch); 
+                appSearchData, globalSearch); 
     }
 
     /**
@@ -3446,7 +3447,11 @@
      * @see #startActivity
      */
     public void startActivityForResult(Intent intent, int requestCode) {
-        startActivityForResult(intent, requestCode, null);
+        Bundle options = null;
+        if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+            options = ActivityOptions.makeSceneTransitionAnimation(null).toBundle();
+        }
+        startActivityForResult(intent, requestCode, options);
     }
 
     /**
@@ -3484,12 +3489,15 @@
      * @see #startActivity
      */
     public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
-        TransitionManager tm = getContentTransitionManager();
-        if (tm != null && options != null) {
+        if (options != null) {
             ActivityOptions activityOptions = new ActivityOptions(options);
             if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
-                getWindow().startExitTransition(activityOptions);
-                options = activityOptions.toBundle();
+                if (mActionBar != null) {
+                    ArrayMap<String, View> sharedElementMap = new ArrayMap<String, View>();
+                    mActionBar.captureSharedElements(sharedElementMap);
+                    activityOptions.addSharedElements(sharedElementMap);
+                }
+                options = mWindow.startExitTransition(activityOptions);
             }
         }
         if (mParent == null) {
@@ -3664,7 +3672,7 @@
      */
     @Override
     public void startActivity(Intent intent) {
-        startActivity(intent, null);
+        this.startActivity(intent, null);
     }
 
     /**
@@ -4720,7 +4728,8 @@
      */
     public final void setProgressBarIndeterminate(boolean indeterminate) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
-                indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF);
+                indeterminate ? Window.PROGRESS_INDETERMINATE_ON
+                        : Window.PROGRESS_INDETERMINATE_OFF);
     }
     
     /**
@@ -5330,12 +5339,6 @@
                 mTransitionActivityOptions = activityOptions;
                 sceneTransitionListener = new Window.SceneTransitionListener() {
                     @Override
-                    public void enterSharedElement(Bundle transitionArgs) {
-                        startSharedElementTransition(transitionArgs);
-                        mTransitionActivityOptions = null;
-                    }
-
-                    @Override
                     public void nullPendingTransition() {
                         overridePendingTransition(0, 0);
                     }
@@ -5349,6 +5352,16 @@
                     public void convertToTranslucent() {
                         Activity.this.convertToTranslucent(null);
                     }
+
+                    @Override
+                    public void sharedElementStart(Transition transition) {
+                        Activity.this.onCaptureSharedElementStart(transition);
+                    }
+
+                    @Override
+                    public void sharedElementEnd() {
+                        Activity.this.onCaptureSharedElementEnd();
+                    }
                 };
 
             }
@@ -5542,53 +5555,23 @@
     }
 
     /**
-     * Gets the entering Activity transition args. Will be null if
-     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)} was
-     * not used to pass a Bundle to startActivity. The Bundle passed to that method in the
-     * calling Activity is returned here.
-     * <p>After startSharedElementTransition is called, this method will return null.</p>
+     * Called when setting up Activity Scene transitions when the start state for shared
+     * elements has been captured. Override this method to modify the start position of shared
+     * elements for the entry Transition.
      *
-     * @return The Bundle passed into Bundle parameter of
-     *         {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)}
-     *         in the calling Activity.
+     * @param transition The <code>Transition</code> being used to change
+     *                   bounds of shared elements in the source Activity to
+     *                   the bounds defined by the entering Scene.
      */
-    public Bundle getTransitionArgs() {
-        if (mTransitionActivityOptions == null) {
-            return null;
-        }
-        return mTransitionActivityOptions.getSceneTransitionArgs();
+    public void onCaptureSharedElementStart(Transition transition) {
     }
 
     /**
-     * Override to transfer a shared element from a calling Activity to this Activity.
-     * Shared elements will be made VISIBLE before this call. The Activity is responsible
-     * for transitioning the shared elements from their location to the eventual destination.
-     * The shared element will be laid out a the destination when this method is called.
-     *
-     * @param transitionArgs The same as returned from {@link #getTransitionArgs()}, this should
-     *                       contain information from the calling Activity to tell where the
-     *                       shared element should be placed.
+     * Called when setting up Activity Scene transitions when the final state for
+     * shared elements state has been captured. Override this method to modify the destination
+     * position of shared elements for the entry Transition.
      */
-    protected void startSharedElementTransition(Bundle transitionArgs) {
-    }
-
-    /**
-     * Controls how the background fade is triggered when there is an entering Activity transition.
-     * If fadeEarly is true, the Window background will fade in as soon as the shared elements are
-     * ready to switch. If fadeEarly is false, the background will fade only after the calling
-     * Activity's exit transition completes. By default, the Window will fade in when the calling
-     * Activity's exit transition completes.
-     *
-     * @param fadeEarly Set to true to fade out the exiting Activity as soon as the shared elements
-     *                  are transferred. Set to false to fade out the exiting Activity as soon as
-     *                  the shared element is transferred.
-     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
-     */
-    public void setEarlyBackgroundTransition(boolean fadeEarly) {
-        if (mTransitionActivityOptions == null) {
-            return;
-        }
-        mWindow.setEarlyBackgroundTransition(fadeEarly);
+    public void onCaptureSharedElementEnd() {
     }
 
     /**
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b40008e..f4358e9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1713,6 +1713,15 @@
             return true;
         }
 
+        case START_USER_IN_BACKGROUND_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int userid = data.readInt();
+            boolean result = startUserInBackground(userid);
+            reply.writeNoException();
+            reply.writeInt(result ? 1 : 0);
+            return true;
+        }
+
         case STOP_USER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int userid = data.readInt();
@@ -1843,6 +1852,17 @@
             return true;
         }
 
+        case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IIntentSender r = IIntentSender.Stub.asInterface(
+                data.readStrongBinder());
+            String prefix = data.readString();
+            String tag = getTagForIntentSender(r, prefix);
+            reply.writeNoException();
+            reply.writeString(tag);
+            return true;
+        }
+
         case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -2038,6 +2058,15 @@
             return true;
         }
 
+        case DELETE_ACTIVITY_CONTAINER_TRANSACTION:  {
+            data.enforceInterface(IActivityManager.descriptor);
+            IActivityContainer activityContainer =
+                    IActivityContainer.Stub.asInterface(data.readStrongBinder());
+            deleteActivityContainer(activityContainer);
+            reply.writeNoException();
+            return true;
+        }
+
         case GET_ACTIVITY_CONTAINER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder activityToken = data.readStrongBinder();
@@ -4284,6 +4313,19 @@
         return result;
     }
 
+    public boolean startUserInBackground(int userid) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(userid);
+        mRemote.transact(START_USER_IN_BACKGROUND_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
+
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -4426,6 +4468,21 @@
         return res;
     }
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        data.writeString(prefix);
+        mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        String res = reply.readString();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -4697,6 +4754,18 @@
         return res;
     }
 
+    public void deleteActivityContainer(IActivityContainer activityContainer)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(activityContainer.asBinder());
+        mRemote.transact(DELETE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
             throws RemoteException {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 3f97c40..07247ff 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.animation.Animator;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.os.Bundle;
@@ -24,8 +23,8 @@
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.transition.Transition;
-import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.view.View;
 
 import java.util.ArrayList;
@@ -100,12 +99,6 @@
     public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
 
     /**
-     * Arguments for the scene transition about to begin.
-     * @hide
-     */
-    public static final String KEY_SCENE_TRANSITION_ARGS = "android:sceneTransitionArgs";
-
-    /**
      * For Activity transitions, the calling Activity's TransitionListener used to
      * notify the called Activity when the shared element and the exit transitions
      * complete.
@@ -120,9 +113,15 @@
     private static final String KEY_TRANSITION_TARGET_LISTENER = "android:transitionTargetListener";
 
     /**
-     * The shared element's texture ID (TODO: not used yet).
+     * The names of shared elements that are transitioned to the started Activity.
+     * This is also the name of shared elements that the started Activity accepted.
      */
-    private static final String KEY_SHARED_ELEMENT_TEXTURE_ID = "android:sharedElementTextureId";
+    private static final String KEY_SHARED_ELEMENT_NAMES = "android:shared_element_names";
+
+    /**
+     * The shared elements names of the views in the calling Activity.
+     */
+    private static final String KEY_LOCAL_ELEMENT_NAMES = "android:local_element_names";
 
     /** @hide */
     public static final int ANIM_NONE = 0;
@@ -146,9 +145,10 @@
     private int mStartY;
     private int mStartWidth;
     private int mStartHeight;
-    private Bundle mTransitionArgs;
     private IRemoteCallback mAnimationStartedListener;
     private IRemoteCallback mTransitionCompleteListener;
+    private ArrayList<String> mSharedElementNames;
+    private ArrayList<String> mLocalElementNames;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -226,7 +226,7 @@
 
     /** @hide */
     public interface ActivityTransitionTarget {
-        void sharedElementTransitionComplete();
+        void sharedElementTransitionComplete(Bundle transitionArgs);
         void exitTransitionComplete();
     }
 
@@ -348,35 +348,51 @@
     }
 
     /**
-     * Create an ActivityOptions to transition between Activities using cross-Activity animation.
-     * When visual elements are to carry between Activities, args should be used to tell the called
-     * Activity about the location and size.
-     *
-     * TODO: Provide facility to capture layout and bitmap of shared elements.
-     *
-     * <p>When
-     * {@link android.app.Activity#startActivities(android.content.Intent[], android.os.Bundle)}
-     * is used with the {@link #toBundle()} result, the Activity's content scene will automatically
-     * transition out by setting their visibility to {@link View#INVISIBLE}. Shared elements
-     * ({@link android.view.View#setSharedElementName(String)}) are unmodified during the
-     * transition to allow the started Activity to seamlessly take it over. ViewGroups typically
-     * don't transition out, and instead transition out their children unless they have a
-     * background. To modify this behavior, use
-     * {@link android.view.ViewGroup#setTransitionGroup(boolean)}.</p>
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of one shared element to the started Activity.
      *
      * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
      * enabled on the calling Activity to cause an exit transition. The same must be in
      * the called Activity to get an entering transition.</p>
-     *
-     * @param args Contains information for transferring a view between this Activity and the
-     *             target Activity. Will be used by the called Activity to transition the
-     *             view to its eventual destination
-     * @see android.app.Activity#startSharedElementTransition(android.os.Bundle)
+     * @param sharedElement The View to transition to the started Activity. sharedElement must
+     *                      have a non-null sharedElementName.
+     * @param sharedElementName The shared element name as used in the target Activity. This may
+     *                          be null if it has the same name as sharedElement.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
      */
-    public static ActivityOptions makeSceneTransitionAnimation(Bundle args) {
+    public static ActivityOptions makeSceneTransitionAnimation(View sharedElement,
+            String sharedElementName) {
+        return makeSceneTransitionAnimation(
+                new Pair<View, String>(sharedElement, sharedElementName));
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of multiple shared elements to the started
+     * Activity.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param sharedElements The View to transition to the started Activity along with the
+     *                       shared element name as used in the started Activity. The view
+     *                       must have a non-null sharedElementName.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(
+            Pair<View, String>... sharedElements) {
         ActivityOptions opts = new ActivityOptions();
         opts.mAnimationType = ANIM_SCENE_TRANSITION;
-        opts.mTransitionArgs = args;
+        opts.mSharedElementNames = new ArrayList<String>();
+        opts.mLocalElementNames = new ArrayList<String>();
+
+        if (sharedElements != null) {
+            for (Pair<View, String> sharedElement : sharedElements) {
+                opts.addSharedElement(sharedElement.first, sharedElement.second);
+            }
+        }
         return opts;
     }
 
@@ -412,9 +428,10 @@
                 break;
 
             case ANIM_SCENE_TRANSITION:
-                mTransitionArgs = opts.getBundle(KEY_SCENE_TRANSITION_ARGS);
                 mTransitionCompleteListener = IRemoteCallback.Stub.asInterface(
                         opts.getBinder(KEY_TRANSITION_COMPLETE_LISTENER));
+                mSharedElementNames = opts.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
+                mLocalElementNames = opts.getStringArrayList(KEY_LOCAL_ELEMENT_NAMES);
                 break;
         }
     }
@@ -465,17 +482,19 @@
     }
 
     /** @hide */
-    public Bundle getSceneTransitionArgs() {
-        return mTransitionArgs;
-    }
-
-    /** @hide */
     public IRemoteCallback getOnAnimationStartListener() {
         return mAnimationStartedListener;
     }
 
     /** @hide */
-    public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target) {
+    public ArrayList<String> getSharedElementNames() { return mSharedElementNames; }
+
+    /** @hide */
+    public ArrayList<String> getLocalElementNames() { return mLocalElementNames; }
+
+    /** @hide */
+    public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target,
+            ArrayList<String> sharedElementNames) {
         boolean listenerSent = false;
         if (mTransitionCompleteListener != null) {
             IRemoteCallback callback = new IRemoteCallback.Stub() {
@@ -484,13 +503,13 @@
                     if (data == null) {
                         target.exitTransitionComplete();
                     } else {
-                        // TODO: Use texture id
-                        target.sharedElementTransitionComplete();
+                        target.sharedElementTransitionComplete(data);
                     }
                 }
             };
             Bundle bundle = new Bundle();
             bundle.putBinder(KEY_TRANSITION_TARGET_LISTENER, callback.asBinder());
+            bundle.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, sharedElementNames);
             try {
                 mTransitionCompleteListener.sendResult(bundle);
                 listenerSent = true;
@@ -499,12 +518,23 @@
             }
         }
         if (!listenerSent) {
-            target.sharedElementTransitionComplete();
+            target.sharedElementTransitionComplete(null);
             target.exitTransitionComplete();
         }
     }
 
     /** @hide */
+    public void dispatchSharedElementsReady() {
+        if (mTransitionCompleteListener != null) {
+            try {
+                mTransitionCompleteListener.sendResult(null);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Couldn't synchronize shared elements", e);
+            }
+        }
+    }
+
+    /** @hide */
     public void abort() {
         if (mAnimationStartedListener != null) {
             try {
@@ -530,6 +560,8 @@
         if (otherOptions.mPackageName != null) {
             mPackageName = otherOptions.mPackageName;
         }
+        mSharedElementNames = null;
+        mLocalElementNames = null;
         switch (otherOptions.mAnimationType) {
             case ANIM_CUSTOM:
                 mAnimationType = otherOptions.mAnimationType;
@@ -544,7 +576,6 @@
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
                 mTransitionCompleteListener = null;
-                mTransitionArgs = null;
                 break;
             case ANIM_SCALE_UP:
                 mAnimationType = otherOptions.mAnimationType;
@@ -560,7 +591,6 @@
                 }
                 mAnimationStartedListener = null;
                 mTransitionCompleteListener = null;
-                mTransitionArgs = null;
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
@@ -576,14 +606,14 @@
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
                 mTransitionCompleteListener = null;
-                mTransitionArgs = null;
                 break;
             case ANIM_SCENE_TRANSITION:
                 mAnimationType = otherOptions.mAnimationType;
                 mTransitionCompleteListener = otherOptions.mTransitionCompleteListener;
-                mTransitionArgs = otherOptions.mTransitionArgs;
                 mThumbnail = null;
                 mAnimationStartedListener = null;
+                mSharedElementNames = otherOptions.mSharedElementNames;
+                mLocalElementNames = otherOptions.mLocalElementNames;
                 break;
         }
     }
@@ -627,11 +657,12 @@
                 break;
             case ANIM_SCENE_TRANSITION:
                 b.putInt(KEY_ANIM_TYPE, mAnimationType);
-                b.putBundle(KEY_SCENE_TRANSITION_ARGS, mTransitionArgs);
                 if (mTransitionCompleteListener != null) {
                     b.putBinder(KEY_TRANSITION_COMPLETE_LISTENER,
                             mTransitionCompleteListener.asBinder());
                 }
+                b.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, mSharedElementNames);
+                b.putStringArrayList(KEY_LOCAL_ELEMENT_NAMES, mLocalElementNames);
                 break;
         }
         return b;
@@ -652,32 +683,52 @@
     }
 
     /** @hide */
-    public interface SharedElementSource {
-        int getTextureId();
+    public void addSharedElements(Map<String, View> sharedElements) {
+        for (Map.Entry<String, View> entry : sharedElements.entrySet()) {
+            addSharedElement(entry.getValue(), entry.getKey());
+        }
     }
 
-    /**
-     * In the calling Activity when transitioning out, sets the Transition to listen for
-     * changes.
-     * @hide
-     */
-    public void setExitTransition(Transition transition, SharedElementSource sharedElementSource) {
-        mTransitionCompleteListener = new ExitTransitionListener(transition, sharedElementSource);
+    /** @hide */
+    public void updateSceneTransitionAnimation(Transition exitTransition,
+            Transition sharedElementTransition, SharedElementSource sharedElementSource) {
+        mTransitionCompleteListener = new ExitTransitionListener(exitTransition,
+                sharedElementTransition, sharedElementSource);
+    }
+
+    private void addSharedElement(View view, String name) {
+        String sharedElementName = view.getSharedElementName();
+        if (name == null) {
+            name = sharedElementName;
+        }
+        mSharedElementNames.add(name);
+        mLocalElementNames.add(sharedElementName);
+    }
+
+    /** @hide */
+    public interface SharedElementSource {
+        Bundle getSharedElementExitState();
+        void acceptedSharedElements(ArrayList<String> sharedElementNames);
+        void hideSharedElements();
     }
 
     private static class ExitTransitionListener extends IRemoteCallback.Stub
-            implements Transition.TransitionListener, Animator.AnimatorListener {
-        private ArrayList<Animator> mSharedElementAnimators = new ArrayList<Animator>();
+            implements Transition.TransitionListener {
         private boolean mSharedElementNotified;
         private Transition mExitTransition;
+        private Transition mSharedElementTransition;
         private IRemoteCallback mTransitionCompleteCallback;
         private boolean mExitComplete;
+        private boolean mSharedElementComplete;
         private SharedElementSource mSharedElementSource;
 
-        public ExitTransitionListener(Transition transition, SharedElementSource sharedElementSource) {
+        public ExitTransitionListener(Transition exitTransition, Transition sharedElementTransition,
+                SharedElementSource sharedElementSource) {
             mSharedElementSource = sharedElementSource;
-            mExitTransition = transition;
+            mExitTransition = exitTransition;
             mExitTransition.addListener(this);
+            mSharedElementTransition = sharedElementTransition;
+            mSharedElementTransition.addListener(this);
         }
 
         @Override
@@ -685,36 +736,36 @@
             if (data != null) {
                 mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(
                         data.getBinder(KEY_TRANSITION_TARGET_LISTENER));
+                ArrayList<String> sharedElementNames
+                        = data.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
+                mSharedElementSource.acceptedSharedElements(sharedElementNames);
                 notifySharedElement();
                 notifyExit();
+            } else {
+                mSharedElementSource.hideSharedElements();
             }
         }
 
         @Override
         public void onTransitionStart(Transition transition) {
-            ArrayMap<Animator, Transition.AnimationInfo> runningAnimators
-                    = Transition.getRunningAnimators();
-            for (Map.Entry<Animator, Transition.AnimationInfo> entry : runningAnimators.entrySet()) {
-                if (entry.getValue().view.getSharedElementName() != null) {
-                    mSharedElementAnimators.add(entry.getKey());
-                    entry.getKey().addListener(this);
-                }
-            }
-            notifySharedElement();
         }
 
         @Override
         public void onTransitionEnd(Transition transition) {
-            mExitComplete = true;
-            notifyExit();
-            mExitTransition.removeListener(this);
+            if (transition == mExitTransition) {
+                mExitComplete = true;
+                notifyExit();
+                mExitTransition.removeListener(this);
+            } else {
+                mSharedElementComplete = true;
+                notifySharedElement();
+                mSharedElementTransition.removeListener(this);
+            }
         }
 
         @Override
         public void onTransitionCancel(Transition transition) {
-            mExitComplete = true;
-            notifyExit();
-            mExitTransition.removeListener(this);
+            onTransitionEnd(transition);
         }
 
         @Override
@@ -725,34 +776,13 @@
         public void onTransitionResume(Transition transition) {
         }
 
-        @Override
-        public void onAnimationStart(Animator animation) {
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mSharedElementAnimators.remove(animation);
-            notifySharedElement();
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            mSharedElementAnimators.remove(animation);
-            notifySharedElement();
-        }
-
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-        }
-
         private void notifySharedElement() {
-            if (!mSharedElementNotified && mSharedElementAnimators.isEmpty()
+            if (!mSharedElementNotified && mSharedElementComplete
                     && mTransitionCompleteCallback != null) {
                 mSharedElementNotified = true;
                 try {
-                    Bundle bundle = new Bundle();
-                    bundle.putInt(KEY_SHARED_ELEMENT_TEXTURE_ID, mSharedElementSource.getTextureId());
-                    mTransitionCompleteCallback.sendResult(bundle);
+                    Bundle sharedElementState = mSharedElementSource.getSharedElementExitState();
+                    mTransitionCompleteCallback.sendResult(sharedElementState);
                 } catch (RemoteException e) {
                     Log.w(TAG, "Couldn't notify that the transition ended", e);
                 }
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 14f0829..113f123 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -37,6 +37,7 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 
+/** @hide */
 public class ActivityView extends ViewGroup {
     private final String TAG = "ActivityView";
     private final boolean DEBUG = false;
@@ -107,6 +108,10 @@
         super.onDetachedFromWindow();
         if (mActivityContainer != null) {
             detach();
+            try {
+                ActivityManagerNative.getDefault().deleteActivityContainer(mActivityContainer);
+            } catch (RemoteException e) {
+            }
             mActivityContainer = null;
         }
     }
@@ -122,7 +127,6 @@
             case  View.INVISIBLE:
                 break;
             case View.GONE:
-                detach();
                 break;
         }
     }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6b48130..061e5a5 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1059,7 +1059,7 @@
     }
 
     @Override
-	  public void installPackageWithVerificationAndEncryption(Uri packageURI,
+    public void installPackageWithVerificationAndEncryption(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
         try {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index c8f1280..20198f9 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -714,7 +714,7 @@
     }
 
     public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
-    		throws RemoteException {
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
@@ -884,7 +884,7 @@
     }
 
     public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-	    int flags, Intent args) throws RemoteException {
+            int flags, Intent args) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7efb3f1..9b3643c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -63,7 +63,7 @@
 import android.location.LocationManager;
 import android.media.AudioManager;
 import android.media.MediaRouter;
-import android.media.MediaSessionManager;
+import android.media.session.MediaSessionManager;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.net.INetworkPolicyManager;
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index c09da87..6c0d379 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -1405,6 +1405,7 @@
         mRestored = false;
         mBackStackNesting = 0;
         mFragmentManager = null;
+        mChildFragmentManager = null;
         mActivity = null;
         mFragmentId = 0;
         mContainerId = 0;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index bf2a629..76f9d97 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1026,6 +1026,7 @@
                                     f.mActivity = null;
                                     f.mParentFragment = null;
                                     f.mFragmentManager = null;
+                                    f.mChildFragmentManager = null;
                                 }
                             }
                         }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8c7fe10..1943bba 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -349,6 +349,7 @@
 
     // Multi-user APIs
     public boolean switchUser(int userid) throws RemoteException;
+    public boolean startUserInBackground(int userid) throws RemoteException;
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
     public UserInfo getCurrentUser() throws RemoteException;
     public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
@@ -367,6 +368,8 @@
 
     public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException;
 
     public long[] getProcessPss(int[] pids) throws RemoteException;
@@ -408,9 +411,13 @@
 
     public void performIdleMaintenance() throws RemoteException;
 
+    /** @hide */
     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
             IActivityContainerCallback callback) throws RemoteException;
 
+    /** @hide */
+    public void deleteActivityContainer(IActivityContainer container) throws RemoteException;
+
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
             throws RemoteException;
 
@@ -704,4 +711,10 @@
     int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
     int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
     int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
+    int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
+
+
+    // Start of L transactions
+    int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
+    int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7926595..b067cd0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -204,6 +204,15 @@
      */
     public RemoteViews bigContentView;
 
+
+    /**
+     * @hide
+     * A medium-format version of {@link #contentView}, giving the Notification an
+     * opportunity to add action buttons to contentView. The system UI may
+     * choose to show this as a popup notification at its discretion.
+     */
+    public RemoteViews headsUpContentView;
+
     /**
      * The bitmap that may escape the bounds of the panel and bar.
      */
@@ -809,6 +818,10 @@
             bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
         }
 
+        if (parcel.readInt() != 0) {
+            headsUpContentView = RemoteViews.CREATOR.createFromParcel(parcel);
+        }
+
         visibility = parcel.readInt();
 
         if (parcel.readInt() != 0) {
@@ -899,6 +912,10 @@
             that.bigContentView = this.bigContentView.clone();
         }
 
+        if (heavy && this.headsUpContentView != null) {
+            that.headsUpContentView = this.headsUpContentView.clone();
+        }
+
         that.visibility = this.visibility;
 
         if (this.publicVersion != null) {
@@ -920,6 +937,7 @@
         tickerView = null;
         contentView = null;
         bigContentView = null;
+        headsUpContentView = null;
         largeIcon = null;
         if (extras != null) {
             extras.remove(Notification.EXTRA_LARGE_ICON);
@@ -1032,6 +1050,13 @@
             parcel.writeInt(0);
         }
 
+        if (headsUpContentView != null) {
+            parcel.writeInt(1);
+            headsUpContentView.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
+
         parcel.writeInt(visibility);
 
         if (publicVersion != null) {
@@ -1182,6 +1207,9 @@
         if (bigContentView != null) {
             bigContentView.setUser(user);
         }
+        if (headsUpContentView != null) {
+            headsUpContentView.setUser(user);
+        }
     }
 
     /**
@@ -1881,6 +1909,13 @@
             return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
         }
 
+        private RemoteViews makeHEadsUpContentView() {
+            if (mActions.size() == 0) return null;
+
+            return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
+        }
+
+
         private RemoteViews generateActionButton(Action action) {
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new RemoteViews(mContext.getPackageName(),
@@ -1921,6 +1956,7 @@
             n.defaults = mDefaults;
             n.flags = mFlags;
             n.bigContentView = makeBigContentView();
+            n.headsUpContentView = makeHEadsUpContentView();
             if (mLedOnMs != 0 || mLedOffMs != 0) {
                 n.flags |= FLAG_SHOW_LIGHTS;
             }
diff --git a/core/java/android/app/OnActivityPausedListener.java b/core/java/android/app/OnActivityPausedListener.java
index 379f133..5003973 100644
--- a/core/java/android/app/OnActivityPausedListener.java
+++ b/core/java/android/app/OnActivityPausedListener.java
@@ -5,7 +5,7 @@
  * 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
+ *        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,
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index d4de112..8efc14f 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -889,6 +889,20 @@
     }
 
     /**
+     * @hide
+     * Return descriptive tag for this PendingIntent.
+     */
+    public String getTag(String prefix) {
+        try {
+            return ActivityManagerNative.getDefault()
+                .getTagForIntentSender(mTarget, prefix);
+        } catch (RemoteException e) {
+            // Should never happen.
+            return null;
+        }
+    }
+
+    /**
      * Comparison operator on two PendingIntent objects, such that true
      * is returned then they both represent the same operation from the
      * same package.  This allows you to use {@link #getActivity},
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 7b8b286..4b33799 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -172,7 +172,7 @@
      * <p>This field corresponds to the <code>android:previewImage</code> attribute in
      * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
      */
-	public int previewImage;
+    public int previewImage;
 
     /**
      * The rules by which a widget can be resized. See {@link #RESIZE_NONE},
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 8694416..f3c803d 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1540,7 +1540,7 @@
      * for a whole class of content.
      * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code>
      * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI
-     * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values
+     * specified by <em>uri</em> will cause notifications to be sent. If <code>true</code>, any URI values
      * at or below the specified URI will also trigger a match.
      * @param observer The object that receives callbacks when changes occur.
      * @see #unregisterContentObserver
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d05d1a1..81a886a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2352,10 +2352,10 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
-     * {@link android.media.MediaSessionManager} for managing media Sessions.
+     * {@link android.media.session.MediaSessionManager} for managing media Sessions.
      *
      * @see #getSystemService
-     * @see android.media.MediaSessionManager
+     * @see android.media.session.MediaSessionManager
      */
     public static final String MEDIA_SESSION_SERVICE = "media_session";
 
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 785f2b4..ef0c4d5 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -209,6 +209,19 @@
      */
     public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;
     /**
+     * Flag for {@link #requiredForProfile}
+     * The application will always be installed for a restricted profile.
+     * @hide
+     */
+    public static final int RESTRICTED_PROFILE = 1;
+    /**
+     * Flag for {@link #requiredForProfile}
+     * The application will always be installed for a managed profile.
+     * @hide
+     */
+    public static final int MANAGED_PROFILE = 2;
+
+    /**
      * The install location requested by the activity.  From the
      * {@link android.R.attr#installLocation} attribute, one of
      * {@link #INSTALL_LOCATION_AUTO},
@@ -218,6 +231,12 @@
      */
     public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
 
+    /**
+     * Defines which profiles this app is required for.
+     * @hide
+     */
+    public int requiredForProfile;
+
     /** @hide */
     public boolean requiredForAllUsers;
 
@@ -276,6 +295,7 @@
         dest.writeTypedArray(reqFeatures, parcelableFlags);
         dest.writeInt(installLocation);
         dest.writeInt(requiredForAllUsers ? 1 : 0);
+        dest.writeInt(requiredForProfile);
         dest.writeString(restrictedAccountType);
         dest.writeString(requiredAccountType);
         dest.writeString(overlayTarget);
@@ -318,6 +338,7 @@
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
         installLocation = source.readInt();
         requiredForAllUsers = source.readInt() != 0;
+        requiredForProfile = source.readInt();
         restrictedAccountType = source.readString();
         requiredAccountType = source.readString();
         overlayTarget = source.readString();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 7fa9417..c222003 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -304,6 +304,7 @@
         if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
                 || (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
             pi.requiredForAllUsers = p.mRequiredForAllUsers;
+            pi.requiredForProfile = p.mRequiredForProfile;
         }
         pi.restrictedAccountType = p.mRestrictedAccountType;
         pi.requiredAccountType = p.mRequiredAccountType;
@@ -1978,6 +1979,8 @@
                 false)) {
             owner.mRequiredForAllUsers = true;
         }
+        owner.mRequiredForProfile = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestApplication_requiredForProfile, 0);
 
         String restrictedAccountType = sa.getString(com.android.internal.R.styleable
                 .AndroidManifestApplication_restrictedAccountType);
@@ -3565,6 +3568,9 @@
         /* An app that's required for all users and cannot be uninstalled for a user */
         public boolean mRequiredForAllUsers;
 
+        /* For which types of profile this app is required */
+        public int mRequiredForProfile;
+
         /* The restricted account authenticator type that is used by this application */
         public String mRestrictedAccountType;
 
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index aa4a243..6f1d4f8 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 
 /**
@@ -116,6 +117,14 @@
         return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
     }
 
+    /**
+     * @return true if this user can be switched to.
+     **/
+    public boolean supportsSwitchTo() {
+        // TODO remove fw.show_hidden_users when we have finished developing managed profiles.
+        return !isManagedProfile() || SystemProperties.getBoolean("fw.show_hidden_users", false);
+    }
+
     public UserInfo() {
     }
 
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 352825f..a41b4f9 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -539,7 +539,7 @@
          * @hide
          */
         public final int getAssetInt() {
-            return (int) mAsset;
+            throw new UnsupportedOperationException();
         }
         /**
          * @hide
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 0369825..ef05732 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -361,7 +361,7 @@
             mP[0] = new float[] { 1.0f };
             mPDeriv[0] = new float[] { 0.0f };
             for (int n = 1; n <= maxN; n++) {
-            	mP[n] = new float[n + 1];
+                mP[n] = new float[n + 1];
                 mPDeriv[n] = new float[n + 1];
                 for (int m = 0; m <= n; m++) {
                     if (n == m) {
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index c4b07cc..ff12d77 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -999,7 +999,7 @@
     /**
      * <p>Use specific scene mode. Enabling this disables
      * control.aeMode, control.awbMode and control.afMode
-     * controls; the HAL must ignore those settings while
+     * controls; the camera device will ignore those settings while
      * USE_SCENE_MODE is active (except for FACE_PRIORITY
      * scene mode). Other control entries are still active.
      * This setting can only be used if availableSceneModes !=
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index dfde11b..c8668f5 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -390,7 +390,7 @@
 
     /**
      * <p>Gains applying to Bayer raw color channels for
-     * white-balance</p>
+     * white-balance.</p>
      * <p>The 4-channel white-balance gains are defined in
      * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
      * for green pixels on even rows of the output, and <code>G_odd</code>
@@ -398,11 +398,11 @@
      * does not support a separate gain for even/odd green channels,
      * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
      * <code>G_even</code> in the output result metadata.</p>
-     * <p>This array is either set by HAL when the request
+     * <p>This array is either set by the camera device when the request
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
      * directly by the application in the request when the
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
-     * <p>The output should be the gains actually applied by the HAL to
+     * <p>The output should be the gains actually applied by the camera device to
      * the current frame.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -536,9 +536,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the metering region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -579,13 +579,15 @@
     /**
      * <p>Whether AF is currently enabled, and what
      * mode it is set to</p>
-     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
+     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+     * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
      * <p>If the lens is controlled by the camera device auto-focus algorithm,
      * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
      * in result metadata.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -609,9 +611,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific focus area
-     * needs to be used by the HAL. If the focusing region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the focusing region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -651,14 +653,14 @@
     /**
      * <p>Whether AWB is currently setting the color
      * transform fields, and what its illumination target
-     * is</p>
+     * is.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
      * <p>When set to the ON mode, the camera device's auto white balance
      * routine is enabled, overriding the application's selected
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to the OFF mode, the camera device's auto white balance
-     * routine is disabled. The applicantion manually controls the white
+     * routine is disabled. The application manually controls the white
      * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
      * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to any other modes, the camera device's auto white balance
@@ -695,10 +697,10 @@
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
-     * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+     * needs to be used by the camera device. If the AWB region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -753,7 +755,7 @@
 
     /**
      * <p>Overall mode of 3A control
-     * routines</p>
+     * routines.</p>
      * <p>High-level 3A control. When set to OFF, all 3A control
      * by the camera device is disabled. The application must set the fields for
      * capture parameters itself.</p>
@@ -830,9 +832,9 @@
 
     /**
      * <p>Operation mode for edge
-     * enhancement</p>
+     * enhancement.</p>
      * <p>Edge/sharpness/detail enhancement. OFF means no
-     * enhancement will be applied by the HAL.</p>
+     * enhancement will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
      * will be applied. HIGH_QUALITY mode indicates that the
      * camera device will use the highest-quality enhancement algorithms,
@@ -1044,7 +1046,7 @@
      * <p>Mode of operation for the noise reduction
      * algorithm</p>
      * <p>Noise filtering control. OFF means no noise reduction
-     * will be applied by the HAL.</p>
+     * will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
      * will be applied. HIGH_QUALITY mode indicates that the camera device
      * will use the highest-quality noise filtering algorithms,
@@ -1285,8 +1287,8 @@
             new Key<Integer>("android.statistics.faceDetectMode", int.class);
 
     /**
-     * <p>Whether the HAL needs to output the lens
-     * shading map in output result metadata</p>
+     * <p>Whether the camera device will output the lens
+     * shading map in output result metadata.</p>
      * <p>When set to ON,
      * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} must be provided in
      * the output result metadata.</p>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 9981bf9..0749edd 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -143,7 +143,7 @@
 
     /**
      * <p>Gains applying to Bayer raw color channels for
-     * white-balance</p>
+     * white-balance.</p>
      * <p>The 4-channel white-balance gains are defined in
      * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
      * for green pixels on even rows of the output, and <code>G_odd</code>
@@ -151,11 +151,11 @@
      * does not support a separate gain for even/odd green channels,
      * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
      * <code>G_even</code> in the output result metadata.</p>
-     * <p>This array is either set by HAL when the request
+     * <p>This array is either set by the camera device when the request
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
      * directly by the application in the request when the
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
-     * <p>The output should be the gains actually applied by the HAL to
+     * <p>The output should be the gains actually applied by the camera device to
      * the current frame.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -225,9 +225,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the metering region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -437,13 +437,15 @@
     /**
      * <p>Whether AF is currently enabled, and what
      * mode it is set to</p>
-     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
+     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+     * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
      * <p>If the lens is controlled by the camera device auto-focus algorithm,
      * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
      * in result metadata.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -467,9 +469,9 @@
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
      * <p>If all regions have 0 weight, then no specific focus area
-     * needs to be used by the HAL. If the focusing region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * needs to be used by the camera device. If the focusing region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -889,14 +891,14 @@
     /**
      * <p>Whether AWB is currently setting the color
      * transform fields, and what its illumination target
-     * is</p>
+     * is.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
      * <p>When set to the ON mode, the camera device's auto white balance
      * routine is enabled, overriding the application's selected
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to the OFF mode, the camera device's auto white balance
-     * routine is disabled. The applicantion manually controls the white
+     * routine is disabled. The application manually controls the white
      * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
      * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
      * <p>When set to any other modes, the camera device's auto white balance
@@ -933,10 +935,10 @@
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
      * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.</p>
-     * <p>If all regions have 0 weight, then no specific metering area
-     * needs to be used by the HAL. If the metering region is
-     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
-     * should ignore the sections outside the region and output the
+     * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+     * needs to be used by the camera device. If the AWB region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
      * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
@@ -1077,7 +1079,7 @@
 
     /**
      * <p>Overall mode of 3A control
-     * routines</p>
+     * routines.</p>
      * <p>High-level 3A control. When set to OFF, all 3A control
      * by the camera device is disabled. The application must set the fields for
      * capture parameters itself.</p>
@@ -1105,9 +1107,9 @@
 
     /**
      * <p>Operation mode for edge
-     * enhancement</p>
+     * enhancement.</p>
      * <p>Edge/sharpness/detail enhancement. OFF means no
-     * enhancement will be applied by the HAL.</p>
+     * enhancement will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
      * will be applied. HIGH_QUALITY mode indicates that the
      * camera device will use the highest-quality enhancement algorithms,
@@ -1385,7 +1387,7 @@
      * <p>Mode of operation for the noise reduction
      * algorithm</p>
      * <p>Noise filtering control. OFF means no noise reduction
-     * will be applied by the HAL.</p>
+     * will be applied by the camera device.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
      * will be applied. HIGH_QUALITY mode indicates that the camera device
      * will use the highest-quality noise filtering algorithms,
@@ -1411,7 +1413,7 @@
      * before the FINAL buffer for frame 4. PARTIAL buffers may be returned
      * in any order relative to other frames, but all PARTIAL buffers for a given
      * capture must arrive before the FINAL buffer for that capture. This entry may
-     * only be used by the HAL if quirks.usePartialResult is set to 1.</p>
+     * only be used by the camera device if quirks.usePartialResult is set to 1.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * @hide
      */
@@ -1904,7 +1906,7 @@
 
     /**
      * <p>The best-fit color channel gains calculated
-     * by the HAL's statistics units for the current output frame</p>
+     * by the camera device's statistics units for the current output frame.</p>
      * <p>This may be different than the gains used for this frame,
      * since statistics processing on data from a new frame
      * typically completes after the transform has already been
@@ -1923,11 +1925,11 @@
 
     /**
      * <p>The best-fit color transform matrix estimate
-     * calculated by the HAL's statistics units for the current
-     * output frame</p>
-     * <p>The HAL must provide the estimate from its
+     * calculated by the camera device's statistics units for the current
+     * output frame.</p>
+     * <p>The camera device will provide the estimate from its
      * statistics unit on the white balance transforms to use
-     * for the next frame. These are the values the HAL believes
+     * for the next frame. These are the values the camera device believes
      * are the best fit for the current output frame. This may
      * be different than the transform used for this frame, since
      * statistics processing on data from a new frame typically
diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java
new file mode 100644
index 0000000..92d6f75
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbConfiguration.java
@@ -0,0 +1,178 @@
+/*
+ * 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.hardware.usb;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class representing a configuration on a {@link UsbDevice}.
+ * A USB configuration can have one or more interfaces, each one providing a different
+ * piece of functionality, separate from the other interfaces.
+ * An interface will have one or more {@link UsbEndpoint}s, which are the
+ * channels by which the host transfers data with the device.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about communicating with USB hardware, read the
+ * <a href="{@docRoot}guide/topics/usb/index.html">USB</a> developer guide.</p>
+ * </div>
+ */
+public class UsbConfiguration implements Parcelable {
+
+    private final int mId;
+    private final String mName;
+    private final int mAttributes;
+    private final int mMaxPower;
+    private Parcelable[] mInterfaces;
+
+    /**
+     * Mask for "self-powered" bit in the configuration's attributes.
+     * @see #getAttributes
+     */
+    public static final int ATTR_SELF_POWERED_MASK = 1 << 6;
+
+    /**
+     * Mask for "remote wakeup" bit in the configuration's attributes.
+     * @see #getAttributes
+     */
+    public static final int ATTR_REMOTE_WAKEUP_MASK = 1 << 5;
+
+    /**
+     * UsbConfiguration should only be instantiated by UsbService implementation
+     * @hide
+     */
+    public UsbConfiguration(int id, String name, int attributes, int maxPower) {
+        mId = id;
+        mName = name;
+        mAttributes = attributes;
+        mMaxPower = maxPower;
+    }
+
+    /**
+     * Returns the configuration's ID field.
+     * This is an integer that uniquely identifies the configuration on the device.
+     *
+     * @return the configuration's ID
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the configuration's name.
+     *
+     * @return the configuration's name
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Returns the configuration's attributes field.
+     * This field contains a bit field with the following flags:
+     *
+     * Bit 7: always set to 1
+     * Bit 6: self-powered
+     * Bit 5: remote wakeup enabled
+     * Bit 0-4: reserved
+     * @see #ATTR_SELF_POWERED_MASK
+     * @see #ATTR_REMOTE_WAKEUP_MASK
+     * @return the configuration's attributes
+     */
+    public int getAttributes() {
+        return mAttributes;
+    }
+
+    /**
+     * Returns the configuration's max power consumption, in milliamps.
+     *
+     * @return the configuration's max power
+     */
+    public int getMaxPower() {
+        return mMaxPower * 2;
+    }
+
+    /**
+     * Returns the number of {@link UsbInterface}s this configuration contains.
+     *
+     * @return the number of endpoints
+     */
+    public int getInterfaceCount() {
+        return mInterfaces.length;
+    }
+
+    /**
+     * Returns the {@link UsbInterface} at the given index.
+     *
+     * @return the interface
+     */
+    public UsbInterface getInterface(int index) {
+        return (UsbInterface)mInterfaces[index];
+    }
+
+    /**
+     * Only used by UsbService implementation
+     * @hide
+     */
+    public void setInterfaces(Parcelable[] interfaces) {
+        mInterfaces = interfaces;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("UsbConfiguration[mId=" + mId +
+                ",mName=" + mName + ",mAttributes=" + mAttributes +
+                ",mMaxPower=" + mMaxPower + ",mInterfaces=[");
+        for (int i = 0; i < mInterfaces.length; i++) {
+            builder.append("\n");
+            builder.append(mInterfaces[i].toString());
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public static final Parcelable.Creator<UsbConfiguration> CREATOR =
+        new Parcelable.Creator<UsbConfiguration>() {
+        public UsbConfiguration createFromParcel(Parcel in) {
+            int id = in.readInt();
+            String name = in.readString();
+            int attributes = in.readInt();
+            int maxPower = in.readInt();
+            Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
+            UsbConfiguration configuration = new UsbConfiguration(id, name, attributes, maxPower);
+            configuration.setInterfaces(interfaces);
+            return configuration;
+        }
+
+        public UsbConfiguration[] newArray(int size) {
+            return new UsbConfiguration[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mId);
+        parcel.writeString(mName);
+        parcel.writeInt(mAttributes);
+        parcel.writeInt(mMaxPower);
+        parcel.writeParcelableArray(mInterfaces, 0);
+   }
+}
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index b0ba9c1..d90e06e 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -50,7 +50,10 @@
     private final int mClass;
     private final int mSubclass;
     private final int mProtocol;
-    private final Parcelable[] mInterfaces;
+    private Parcelable[] mConfigurations;
+
+    // list of all interfaces on the device
+    private UsbInterface[] mInterfaces;
 
     /**
      * UsbDevice should only be instantiated by UsbService implementation
@@ -58,8 +61,7 @@
      */
     public UsbDevice(String name, int vendorId, int productId,
             int Class, int subClass, int protocol,
-            String manufacturerName, String productName, String serialNumber,
-            Parcelable[] interfaces) {
+            String manufacturerName, String productName, String serialNumber) {
         mName = name;
         mVendorId = vendorId;
         mProductId = productId;
@@ -69,7 +71,6 @@
         mManufacturerName = manufacturerName;
         mProductName = productName;
         mSerialNumber = serialNumber;
-        mInterfaces = interfaces;
     }
 
     /**
@@ -169,21 +170,74 @@
     }
 
     /**
+     * Returns the number of {@link UsbConfiguration}s this device contains.
+     *
+     * @return the number of configurations
+     */
+    public int getConfigurationCount() {
+        return mConfigurations.length;
+    }
+
+    /**
+     * Returns the {@link UsbConfiguration} at the given index.
+     *
+     * @return the configuration
+     */
+    public UsbConfiguration getConfiguration(int index) {
+        return (UsbConfiguration)mConfigurations[index];
+    }
+
+    private UsbInterface[] getInterfaceList() {
+        if (mInterfaces == null) {
+            int configurationCount = mConfigurations.length;
+            int interfaceCount = 0;
+            for (int i = 0; i < configurationCount; i++) {
+                UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i];
+                interfaceCount += configuration.getInterfaceCount();
+            }
+
+            mInterfaces = new UsbInterface[interfaceCount];
+            int offset = 0;
+            for (int i = 0; i < configurationCount; i++) {
+                UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i];
+                interfaceCount = configuration.getInterfaceCount();
+                for (int j = 0; j < interfaceCount; j++) {
+                    mInterfaces[offset++] = configuration.getInterface(j);
+                }
+            }
+        }
+
+        return mInterfaces;
+    }
+
+    /**
      * Returns the number of {@link UsbInterface}s this device contains.
+     * For devices with multiple configurations, you will probably want to use
+     * {@link UsbConfiguration#getInterfaceCount} instead.
      *
      * @return the number of interfaces
      */
     public int getInterfaceCount() {
-        return mInterfaces.length;
+        return getInterfaceList().length;
     }
 
     /**
      * Returns the {@link UsbInterface} at the given index.
+     * For devices with multiple configurations, you will probably want to use
+     * {@link UsbConfiguration#getInterface} instead.
      *
      * @return the interface
      */
     public UsbInterface getInterface(int index) {
-        return (UsbInterface)mInterfaces[index];
+        return getInterfaceList()[index];
+    }
+
+    /**
+     * Only used by UsbService implementation
+     * @hide
+     */
+    public void setConfigurations(Parcelable[] configuration) {
+        mConfigurations = configuration;
     }
 
     @Override
@@ -204,11 +258,17 @@
 
     @Override
     public String toString() {
-        return "UsbDevice[mName=" + mName + ",mVendorId=" + mVendorId +
-                ",mProductId=" + mProductId + ",mClass=" + mClass +
-                ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
+        StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName +
+                ",mVendorId=" + mVendorId + ",mProductId=" + mProductId +
+                ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
                 ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName +
-                ",mSerialNumber=" + mSerialNumber + ",mInterfaces=" + mInterfaces + "]";
+                ",mSerialNumber=" + mSerialNumber + ",mConfigurations=[");
+        for (int i = 0; i < mConfigurations.length; i++) {
+            builder.append("\n");
+            builder.append(mConfigurations[i].toString());
+        }
+        builder.append("]");
+        return builder.toString();
     }
 
     public static final Parcelable.Creator<UsbDevice> CREATOR =
@@ -223,9 +283,11 @@
             String manufacturerName = in.readString();
             String productName = in.readString();
             String serialNumber = in.readString();
-            Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
-            return new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
-                                 manufacturerName, productName, serialNumber, interfaces);
+            Parcelable[] configurations = in.readParcelableArray(UsbInterface.class.getClassLoader());
+            UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
+                                 manufacturerName, productName, serialNumber);
+            device.setConfigurations(configurations);
+            return device;
         }
 
         public UsbDevice[] newArray(int size) {
@@ -247,7 +309,7 @@
         parcel.writeString(mManufacturerName);
         parcel.writeString(mProductName);
         parcel.writeString(mSerialNumber);
-        parcel.writeParcelableArray(mInterfaces, 0);
+        parcel.writeParcelableArray(mConfigurations, 0);
    }
 
     public static int getDeviceId(String name) {
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 389475f..6283951 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -101,6 +101,25 @@
     }
 
     /**
+     * Sets the current {@link android.hardware.usb.UsbInterface}.
+     * Used to select between two interfaces with the same ID but different alternate setting.
+     *
+     * @return true if the interface was successfully released
+     */
+    public boolean setInterface(UsbInterface intf) {
+        return native_set_interface(intf.getId(), intf.getAlternateSetting());
+    }
+
+    /**
+     * Sets the device's current {@link android.hardware.usb.UsbConfiguration}.
+     *
+     * @return true if the configuration was successfully set
+     */
+    public boolean setConfiguration(UsbConfiguration configuration) {
+        return native_set_configuration(configuration.getId());
+    }
+
+    /**
      * Performs a control transaction on endpoint zero for this device.
      * The direction of the transfer is determined by the request type.
      * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
@@ -236,6 +255,8 @@
     private native byte[] native_get_desc();
     private native boolean native_claim_interface(int interfaceID, boolean force);
     private native boolean native_release_interface(int interfaceID);
+    private native boolean native_set_interface(int interfaceID, int alternateSetting);
+    private native boolean native_set_configuration(int configurationID);
     private native int native_control_request(int requestType, int request, int value,
             int index, byte[] buffer, int offset, int length, int timeout);
     private native int native_bulk_request(int endpoint, byte[] buffer,
diff --git a/core/java/android/hardware/usb/UsbInterface.java b/core/java/android/hardware/usb/UsbInterface.java
index e94baa1..de01a88 100644
--- a/core/java/android/hardware/usb/UsbInterface.java
+++ b/core/java/android/hardware/usb/UsbInterface.java
@@ -35,27 +35,31 @@
 public class UsbInterface implements Parcelable {
 
     private final int mId;
+    private final int mAlternateSetting;
+    private final String mName;
     private final int mClass;
     private final int mSubclass;
     private final int mProtocol;
-    private final Parcelable[] mEndpoints;
+    private Parcelable[] mEndpoints;
 
     /**
      * UsbInterface should only be instantiated by UsbService implementation
      * @hide
      */
-    public UsbInterface(int id, int Class, int subClass, int protocol,
-            Parcelable[] endpoints) {
+    public UsbInterface(int id, int alternateSetting, String name,
+            int Class, int subClass, int protocol) {
         mId = id;
+        mAlternateSetting = alternateSetting;
+        mName = name;
         mClass = Class;
         mSubclass = subClass;
         mProtocol = protocol;
-        mEndpoints = endpoints;
     }
 
     /**
-     * Returns the interface's ID field.
-     * This is an integer that uniquely identifies the interface on the device.
+     * Returns the interface's bInterfaceNumber field.
+     * This is an integer that along with the alternate setting uniquely identifies
+     * the interface on the device.
      *
      * @return the interface's ID
      */
@@ -64,6 +68,28 @@
     }
 
     /**
+     * Returns the interface's bAlternateSetting field.
+     * This is an integer that along with the ID uniquely identifies
+     * the interface on the device.
+     * {@link UsbDeviceConnection#setInterface} can be used to switch between
+     * two interfaces with the same ID but different alternate setting.
+     *
+     * @return the interface's alternate setting
+     */
+    public int getAlternateSetting() {
+        return mAlternateSetting;
+    }
+
+    /**
+     * Returns the interface's name.
+     *
+     * @return the interface's name
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
      * Returns the interface's class field.
      * Some useful constants for USB classes can be found in {@link UsbConstants}
      *
@@ -109,22 +135,42 @@
         return (UsbEndpoint)mEndpoints[index];
     }
 
+    /**
+     * Only used by UsbService implementation
+     * @hide
+     */
+    public void setEndpoints(Parcelable[] endpoints) {
+        mEndpoints = endpoints;
+    }
+
     @Override
     public String toString() {
-        return "UsbInterface[mId=" + mId + ",mClass=" + mClass +
+        StringBuilder builder = new StringBuilder("UsbInterface[mId=" + mId +
+                ",mAlternateSetting=" + mAlternateSetting +
+                ",mName=" + mName + ",mClass=" + mClass +
                 ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
-                ",mEndpoints=" + mEndpoints + "]";
+                ",mEndpoints=[");
+        for (int i = 0; i < mEndpoints.length; i++) {
+            builder.append("\n");
+            builder.append(mEndpoints[i].toString());
+        }
+        builder.append("]");
+        return builder.toString();
     }
 
     public static final Parcelable.Creator<UsbInterface> CREATOR =
         new Parcelable.Creator<UsbInterface>() {
         public UsbInterface createFromParcel(Parcel in) {
             int id = in.readInt();
+            int alternateSetting = in.readInt();
+            String name = in.readString();
             int Class = in.readInt();
             int subClass = in.readInt();
             int protocol = in.readInt();
             Parcelable[] endpoints = in.readParcelableArray(UsbEndpoint.class.getClassLoader());
-            return new UsbInterface(id, Class, subClass, protocol, endpoints);
+            UsbInterface intf = new UsbInterface(id, alternateSetting, name, Class, subClass, protocol);
+            intf.setEndpoints(endpoints);
+            return intf;
         }
 
         public UsbInterface[] newArray(int size) {
@@ -138,6 +184,8 @@
 
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mId);
+        parcel.writeInt(mAlternateSetting);
+        parcel.writeString(mName);
         parcel.writeInt(mClass);
         parcel.writeInt(mSubclass);
         parcel.writeInt(mProtocol);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index e6b9d4c..5b2a29e 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -23,9 +23,14 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
+import android.os.IBinder;
+import android.os.INetworkActivityListener;
+import android.os.INetworkManagementService;
 import android.os.Messenger;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.provider.Settings;
+import android.util.ArrayMap;
 
 import java.net.InetAddress;
 
@@ -76,7 +81,7 @@
 
     /**
      * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
-     * applicable {@link Settings.Secure#CONNECTIVITY_CHANGE_DELAY}.
+     * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
      *
      * @hide
      */
@@ -402,6 +407,8 @@
 
     private final String mPackageName;
 
+    private INetworkManagementService mNMService;
+
     /**
      * Tests if a given integer represents a valid network type.
      * @param networkType the type to be tested
@@ -907,6 +914,92 @@
     }
 
     /**
+     * Callback for use with {@link ConnectivityManager#registerNetworkActiveListener} to
+     * find out when the current network has gone in to a high power state.
+     */
+    public interface OnNetworkActiveListener {
+        /**
+         * Called on the main thread of the process to report that the current data network
+         * has become active, and it is now a good time to perform any pending network
+         * operations.  Note that this listener only tells you when the network becomes
+         * active; if at any other time you want to know whether it is active (and thus okay
+         * to initiate network traffic), you can retrieve its instantaneous state with
+         * {@link ConnectivityManager#isNetworkActive}.
+         */
+        public void onNetworkActive();
+    }
+
+    private INetworkManagementService getNetworkManagementService() {
+        synchronized (this) {
+            if (mNMService != null) {
+                return mNMService;
+            }
+            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+            mNMService = INetworkManagementService.Stub.asInterface(b);
+            return mNMService;
+        }
+    }
+
+    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
+            mNetworkActivityListeners
+                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
+
+    /**
+     * Start listening to reports when the data network is active, meaning it is
+     * a good time to perform network traffic.  Use {@link #isNetworkActive()}
+     * to determine the current state of the network after registering the listener.
+     *
+     * @param l The listener to be told when the network is active.
+     */
+    public void registerNetworkActiveListener(final OnNetworkActiveListener l) {
+        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
+            @Override
+            public void onNetworkActive() throws RemoteException {
+                l.onNetworkActive();
+            }
+        };
+
+        try {
+            getNetworkManagementService().registerNetworkActivityListener(rl);
+            mNetworkActivityListeners.put(l, rl);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Remove network active listener previously registered with
+     * {@link #registerNetworkActiveListener}.
+     *
+     * @param l Previously registered listener.
+     */
+    public void unregisterNetworkActiveListener(OnNetworkActiveListener l) {
+        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
+        if (rl == null) {
+            throw new IllegalArgumentException("Listener not registered: " + l);
+        }
+        try {
+            getNetworkManagementService().unregisterNetworkActivityListener(rl);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Return whether the data network is currently active.  An active network means that
+     * it is currently in a high power state for performing data transmission.  On some
+     * types of networks, it may be expensive to move and stay in such a state, so it is
+     * more power efficient to batch network traffic together when the radio is already in
+     * this state.  This method tells you whether right now is currently a good time to
+     * initiate network traffic, as the network is already active.
+     */
+    public boolean isNetworkActive() {
+        try {
+            return getNetworkManagementService().isNetworkActive();
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
      * {@hide}
      */
     public ConnectivityManager(IConnectivityManager service, String packageName) {
@@ -1021,7 +1114,7 @@
 
     /**
      * Check if the device allows for tethering.  It may be disabled via
-     * {@code ro.tether.denied} system property, {@link Settings#TETHER_SUPPORTED} or
+     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
      * due to device configuration.
      *
      * @return a boolean - {@code true} indicating Tethering is supported.
@@ -1209,7 +1302,7 @@
      * doing something unusual like general internal filtering this may be useful.  On
      * a private network where the proxy is not accessible, you may break HTTP using this.
      *
-     * @param proxyProperties The a {@link ProxyProperites} object defining the new global
+     * @param p The a {@link ProxyProperties} object defining the new global
      *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
      *
      * <p>This method requires the call to hold the permission
@@ -1362,7 +1455,7 @@
     /**
      * Supply the backend messenger for a network tracker
      *
-     * @param type NetworkType to set
+     * @param networkType NetworkType to set
      * @param messenger {@link Messenger}
      * {@hide}
      */
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 25514f4..54d43d3 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -507,6 +507,17 @@
     }
 
     /**
+     * Fast path for battery stats.
+     */
+    public long getTotalPackets() {
+        long total = 0;
+        for (int i = size-1; i >= 0; i--) {
+            total += rxPackets[i] + txPackets[i];
+        }
+        return total;
+    }
+
+    /**
      * Subtract the given {@link NetworkStats}, effectively leaving the delta
      * between two snapshots in time. Assumes that statistics rows collect over
      * time, and that none of them have disappeared.
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index a7d287b..461e8b8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -16,13 +16,24 @@
 
 package android.net;
 
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -31,27 +42,70 @@
  * {@hide}
  */
 public class ProxyDataTracker extends BaseNetworkStateTracker {
-    private static final String NETWORK_TYPE = "PROXY";
     private static final String TAG = "ProxyDataTracker";
+    private static final String NETWORK_TYPE = "PROXY";
 
     // TODO: investigate how to get these DNS addresses from the system.
     private static final String DNS1 = "8.8.8.8";
     private static final String DNS2 = "8.8.4.4";
     private static final String REASON_ENABLED = "enabled";
+    private static final String REASON_DISABLED = "disabled";
+    private static final String REASON_PROXY_DOWN = "proxy_down";
 
+    private static final int MSG_TEAR_DOWN_REQUEST = 1;
+    private static final int MSG_SETUP_REQUEST = 2;
+
+    private static final String PERMISSION_PROXY_STATUS_SENDER =
+            "android.permission.ACCESS_NETWORK_CONDITIONS";
+    private static final String ACTION_PROXY_STATUS_CHANGE =
+            "com.android.net.PROXY_STATUS_CHANGE";
+    private static final String KEY_IS_PROXY_AVAILABLE = "is_proxy_available";
+    private static final String KEY_REPLY_TO_MESSENGER_BINDER = "reply_to_messenger_binder";
+    private static final String KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE =
+            "reply_to_messenger_binder_bundle";
+
+    private Handler mTarget;
+    private Messenger mProxyStatusService;
+    private AtomicBoolean mReconnectRequested = new AtomicBoolean(false);
+    private AtomicBoolean mIsProxyAvailable = new AtomicBoolean(false);
     private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
-    private final AtomicInteger mReconnectGeneration = new AtomicInteger(0);
+
+    private final BroadcastReceiver mProxyStatusServiceListener = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(ACTION_PROXY_STATUS_CHANGE)) {
+                mIsProxyAvailable.set(intent.getBooleanExtra(KEY_IS_PROXY_AVAILABLE, false));
+                if (mIsProxyAvailable.get()) {
+                    Bundle bundle = intent.getBundleExtra(KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE);
+                    if (bundle == null || bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER) == null) {
+                        Log.e(TAG, "no messenger binder in the intent to send future requests");
+                        mIsProxyAvailable.set(false);
+                        return;
+                    }
+                    mProxyStatusService =
+                            new Messenger(bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER));
+                    // If there is a pending reconnect request, do it now.
+                    if (mReconnectRequested.get()) {
+                        reconnect();
+                    }
+                } else {
+                    setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
+                            REASON_PROXY_DOWN, null);
+                }
+            } else {
+                Log.d(TAG, "Unrecognized broadcast intent");
+            }
+        }
+    };
 
     /**
      * Create a new ProxyDataTracker
      */
     public ProxyDataTracker() {
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, "");
-        // TODO: update available state according to proxy state.
-        mNetworkInfo.setIsAvailable(true);
         mLinkProperties = new LinkProperties();
         mLinkCapabilities = new LinkCapabilities();
-
+        mNetworkInfo.setIsAvailable(true);
         try {
           mLinkProperties.addDns(InetAddress.getByName(DNS1));
           mLinkProperties.addDns(InetAddress.getByName(DNS2));
@@ -64,11 +118,31 @@
         throw new CloneNotSupportedException();
     }
 
+    @Override
+    public void startMonitoring(Context context, Handler target) {
+        mContext = context;
+        mTarget = target;
+        mContext.registerReceiver(mProxyStatusServiceListener,
+                new IntentFilter(ACTION_PROXY_STATUS_CHANGE),
+                PERMISSION_PROXY_STATUS_SENDER,
+                null);
+    }
+
     /**
      * Disable connectivity to the network.
      */
     public boolean teardown() {
-        // TODO: tell relevant service to tear down proxy.
+        setTeardownRequested(true);
+        mReconnectRequested.set(false);
+        try {
+            if (mIsProxyAvailable.get() && mProxyStatusService != null) {
+                mProxyStatusService.send(Message.obtain(null, MSG_TEAR_DOWN_REQUEST));
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to connect to proxy status service", e);
+            return false;
+        }
+        setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_DISABLED, null);
         return true;
     }
 
@@ -76,16 +150,24 @@
      * Re-enable proxy data connectivity after a {@link #teardown()}.
      */
     public boolean reconnect() {
-        if (!isAvailable()) {
-            Log.w(TAG, "Reconnect requested even though network is disabled. Bailing.");
+        mReconnectRequested.set(true);
+        setTeardownRequested(false);
+        if (!mIsProxyAvailable.get()) {
+            Log.w(TAG, "Reconnect requested even though proxy service is not up. Bailing.");
             return false;
         }
-        setTeardownRequested(false);
-        mReconnectGeneration.incrementAndGet();
-        // TODO: tell relevant service to setup proxy. Set state to connected only if setup
-        // succeeds.
-        setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
+        setDetailedState(NetworkInfo.DetailedState.CONNECTING, REASON_ENABLED, null);
 
+        try {
+            mProxyStatusService.send(Message.obtain(null, MSG_SETUP_REQUEST));
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to connect to proxy status service", e);
+            setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_PROXY_DOWN, null);
+            return false;
+        }
+        // We'll assume proxy is set up successfully. If not, a status change broadcast will be
+        // received afterwards to indicate any failure.
+        setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
         return true;
     }
 
@@ -116,7 +198,7 @@
     private void setDetailedState(NetworkInfo.DetailedState state, String reason,
             String extraInfo) {
         mNetworkInfo.setDetailedState(state, reason, extraInfo);
-        Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+        Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
         msg.sendToTarget();
     }
 }
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index d7dc7f5..7385dff 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -151,9 +151,10 @@
     }
 
     /**
-     * Protect a socket from VPN connections. The socket will be bound to the
-     * current default network interface, so its traffic will not be forwarded
-     * through VPN. This method is useful if some connections need to be kept
+     * Protect a socket from VPN connections. After protecting, data sent
+     * through this socket will go directly to the underlying network,
+     * so its traffic will not be forwarded through the VPN.
+     * This method is useful if some connections need to be kept
      * outside of VPN. For example, a VPN tunnel should protect itself if its
      * destination is covered by VPN routes. Otherwise its outgoing packets
      * will be sent back to the VPN interface and cause an infinite loop. This
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 10988c6..635a50f 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -48,6 +48,7 @@
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
     void setAppCallback(in IAppCallback callback);
+    void invokeBeam();
 
     void dispatch(in Tag tag);
 
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index de481cf..83d17ba 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -20,6 +20,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
@@ -474,6 +475,45 @@
     }
 
     /**
+     * Create a new NDEF record containing UTF-8 text data.<p>
+     *
+     * The caller can either specify the language code for the provided text,
+     * or otherwise the language code corresponding to the current default
+     * locale will be used.
+     *
+     * Reference specification: NFCForum-TS-RTD_Text_1.0
+     * @param languageCode The languageCode for the record. If locale is empty or null,
+     *                     the language code of the current default locale will be used.
+     * @param text   The text to be encoded in the record. Will be represented in UTF-8 format.
+     * @throws IllegalArgumentException if text is null
+     */
+    public static NdefRecord createTextRecord(String languageCode, String text) {
+        if (text == null) throw new NullPointerException("text is null");
+
+        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
+
+        byte[] languageCodeBytes = null;
+        if (languageCode != null && !languageCode.isEmpty()) {
+            languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
+        } else {
+            languageCodeBytes = Locale.getDefault().getLanguage().
+                    getBytes(StandardCharsets.US_ASCII);
+        }
+        // We only have 6 bits to indicate ISO/IANA language code.
+        if (languageCodeBytes.length >= 64) {
+            throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
+
+        byte status = (byte) (languageCodeBytes.length & 0xFF);
+        buffer.put(status);
+        buffer.put(languageCodeBytes);
+        buffer.put(textBytes);
+
+        return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
+    }
+
+    /**
      * Construct an NDEF Record from its component fields.<p>
      * Recommend to use helpers such as {#createUri} or
      * {{@link #createExternal} where possible, since they perform
@@ -775,7 +815,7 @@
                     throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
                 } else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
                     throw new FormatException("" +
-                    		"unexpected TNF_UNCHANGED in first chunk or unchunked record");
+                            "unexpected TNF_UNCHANGED in first chunk or unchunked record");
                 }
 
                 int typeLength = buffer.get() & 0xFF;
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 77c0234..8643f2e 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.content.Intent;
 import android.net.Uri;
 import android.nfc.NfcAdapter.ReaderCallback;
 import android.os.Binder;
@@ -327,6 +328,7 @@
         NfcAdapter.CreateNdefMessageCallback ndefCallback;
         NfcAdapter.CreateBeamUrisCallback urisCallback;
         NdefMessage message;
+        Activity activity;
         Uri[] uris;
         int flags;
         synchronized (NfcActivityManager.this) {
@@ -338,6 +340,7 @@
             message = state.ndefMessage;
             uris = state.uris;
             flags = state.flags;
+            activity = state.activity;
         }
 
         // Make callbacks without lock
@@ -362,7 +365,13 @@
                 }
             }
         }
-
+        if (uris != null && uris.length > 0) {
+            for (Uri uri : uris) {
+                // Grant the NFC process permission to read these URIs
+                activity.grantUriPermission("com.android.nfc", uri,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            }
+        }
         return new BeamShareData(message, uris, flags);
     }
 
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index e8b7437..96a3947 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -1249,6 +1249,45 @@
     }
 
     /**
+     * Manually invoke Android Beam to share data.
+     *
+     * <p>The Android Beam animation is normally only shown when two NFC-capable
+     * devices come into range.
+     * By calling this method, an Activity can invoke the Beam animation directly
+     * even if no other NFC device is in range yet. The Beam animation will then
+     * prompt the user to tap another NFC-capable device to complete the data
+     * transfer.
+     *
+     * <p>The main advantage of using this method is that it avoids the need for the
+     * user to tap the screen to complete the transfer, as this method already
+     * establishes the direction of the transfer and the consent of the user to
+     * share data. Callers are responsible for making sure that the user has
+     * consented to sharing data on NFC tap.
+     *
+     * <p>Note that to use this method, the passed in Activity must have already
+     * set data to share over Beam by using method calls such as
+     * {@link #setNdefPushMessageCallback} or
+     * {@link #setBeamPushUrisCallback}.
+     *
+     * @param activity the current foreground Activity that has registered data to share
+     * @return whether the Beam animation was successfully invoked
+     */
+    public boolean invokeBeam(Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity may not be null.");
+        }
+        enforceResumed(activity);
+        try {
+            sService.invokeBeam();
+            return true;
+        } catch (RemoteException e) {
+            Log.e(TAG, "invokeBeam: NFC process has died.");
+            attemptDeadServiceRecovery(e);
+            return false;
+        }
+    }
+
+    /**
      * Enable NDEF message push over NFC while this Activity is in the foreground.
      *
      * <p>You must explicitly call this method every time the activity is
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 26e09b6..4f91d19 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -40,7 +40,7 @@
  * and does not constitute a generic threading framework. AsyncTasks should ideally be
  * used for short operations (a few seconds at the most.) If you need to keep threads
  * running for long periods of time, it is highly recommended you use the various APIs
- * provided by the <code>java.util.concurrent</code> pacakge such as {@link Executor},
+ * provided by the <code>java.util.concurrent</code> package such as {@link Executor},
  * {@link ThreadPoolExecutor} and {@link FutureTask}.</p>
  *
  * <p>An asynchronous task is defined by a computation that runs on a background thread and
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 2d67264..8f5cf8b 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -15,9 +15,6 @@
 
 package android.os;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-
 /**
  * {@hide}
  */
@@ -33,6 +30,22 @@
     public int batteryTemperature;
     public String batteryTechnology;
 
+    public BatteryProperties() {
+    }
+
+    public void set(BatteryProperties other) {
+        chargerAcOnline = other.chargerAcOnline;
+        chargerUsbOnline = other.chargerUsbOnline;
+        chargerWirelessOnline = other.chargerWirelessOnline;
+        batteryStatus = other.batteryStatus;
+        batteryHealth = other.batteryHealth;
+        batteryPresent = other.batteryPresent;
+        batteryLevel = other.batteryLevel;
+        batteryVoltage = other.batteryVoltage;
+        batteryTemperature = other.batteryTemperature;
+        batteryTechnology = other.batteryTechnology;
+    }
+
     /*
      * Parcel read/write code must be kept in sync with
      * frameworks/native/services/batteryservice/BatteryProperties.cpp
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index dfba208..a965e00 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -326,6 +326,8 @@
         public abstract boolean hasNetworkActivity();
         public abstract long getNetworkActivityBytes(int type, int which);
         public abstract long getNetworkActivityPackets(int type, int which);
+        public abstract long getMobileRadioActiveTime(int which);
+        public abstract int getMobileRadioActiveCount(int which);
 
         public static abstract class Sensor {
             /*
@@ -588,8 +590,10 @@
         public static final int EVENT_FOREGROUND = 0x0002;
         // Event is about an application package that is at the top of the screen.
         public static final int EVENT_TOP = 0x0003;
+        // Event is about an application package that is at the top of the screen.
+        public static final int EVENT_SYNC = 0x0004;
         // Number of event types.
-        public static final int EVENT_COUNT = 0x0004;
+        public static final int EVENT_COUNT = 0x0005;
 
         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
@@ -597,6 +601,8 @@
         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
+        public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
+        public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
 
         // For CMD_EVENT.
         public int eventCode;
@@ -827,6 +833,13 @@
      */
     public abstract long getScreenOnTime(long batteryRealtime, int which);
     
+    /**
+     * Returns the number of times the screen was turned on.
+     *
+     * {@hide}
+     */
+    public abstract int getScreenOnCount(int which);
+
     public static final int SCREEN_BRIGHTNESS_DARK = 0;
     public static final int SCREEN_BRIGHTNESS_DIM = 1;
     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
@@ -863,6 +876,13 @@
     public abstract long getPhoneOnTime(long batteryRealtime, int which);
     
     /**
+     * Returns the number of times a phone call was activated.
+     *
+     * {@hide}
+     */
+    public abstract int getPhoneOnCount(int which);
+
+    /**
      * Returns the time in microseconds that the phone has been running with
      * the given signal strength.
      * 
@@ -895,6 +915,28 @@
      */
     public abstract long getMobileRadioActiveTime(long batteryRealtime, int which);
 
+    /**
+     * Returns the number of times that the mobile network has transitioned to the
+     * active state.
+     *
+     * {@hide}
+     */
+    public abstract int getMobileRadioActiveCount(int which);
+
+    /**
+     * Returns the time in microseconds that the mobile network has been active
+     * (in a high power state) but not being able to blame on an app.
+     *
+     * {@hide}
+     */
+    public abstract long getMobileRadioActiveUnknownTime(int which);
+
+    /**
+     * Return count of number of times radio was up that could not be blamed on apps.
+     *
+     * {@hide}
+     */
+    public abstract int getMobileRadioActiveUnknownCount(int which);
 
     public static final int DATA_CONNECTION_NONE = 0;
     public static final int DATA_CONNECTION_GPRS = 1;
@@ -975,11 +1017,11 @@
     };
 
     public static final String[] HISTORY_EVENT_NAMES = new String[] {
-            "null", "proc", "fg", "top"
+            "null", "proc", "fg", "top", "sync"
     };
 
     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
-            "Nl", "Pr", "Fg", "Tp"
+            "Enl", "Epr", "Efg", "Etp", "Esy"
     };
 
     /**
@@ -1234,6 +1276,13 @@
         sb.append("ms ");
     }
 
+    private final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
+        long sec = time / 1000;
+        formatTimeRaw(sb, sec);
+        sb.append(time - (sec * 1000));
+        sb.append("ms");
+    }
+
     private final String formatRatioLocked(long num, long den) {
         if (den == 0L) {
             return "--%";
@@ -1586,6 +1635,8 @@
             long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
             long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
             long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+            long mobileActiveTime = u.getMobileRadioActiveTime(which);
+            int mobileActiveCount = u.getMobileRadioActiveCount(which);
             long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
             long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
@@ -1594,11 +1645,12 @@
 
             if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
                     || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
-                    || wifiPacketsTx > 0) {
+                    || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
                 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
                         wifiBytesRx, wifiBytesTx,
                         mobilePacketsRx, mobilePacketsTx,
-                        wifiPacketsRx, wifiPacketsTx);
+                        wifiPacketsRx, wifiPacketsTx,
+                        mobileActiveTime, mobileActiveCount);
             }
 
             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
@@ -1782,7 +1834,7 @@
                 formatTimeMs(sb, totalRealtime / 1000);
                 sb.append("realtime, ");
                 formatTimeMs(sb, totalUptime / 1000);
-                sb.append("uptime, ");
+                sb.append("uptime");
         pw.println(sb.toString());
         pw.print("  Start clock time: ");
         pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
@@ -1796,21 +1848,27 @@
         sb.append(prefix);
                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
-                sb.append("), Input events: "); sb.append(getInputEventCount(which));
-                sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
-                sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
-                sb.append(")");
+                sb.append(") "); sb.append(getScreenOnCount(which));
+                sb.append("x, Input events: "); sb.append(getInputEventCount(which));
         pw.println(sb.toString());
+        if (phoneOnTime != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
+                    sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
+                    sb.append(") "); sb.append(getPhoneOnCount(which));
+        }
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Screen brightnesses: ");
+        sb.append("  Screen brightnesses:");
         boolean didOne = false;
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
             final long time = getScreenBrightnessTime(i, batteryRealtime, which);
             if (time == 0) {
                 continue;
             }
-            if (didOne) sb.append(", ");
+            sb.append("\n    ");
+            sb.append(prefix);
             didOne = true;
             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
             sb.append(" ");
@@ -1819,7 +1877,7 @@
             sb.append(formatRatioLocked(time, screenOnTime));
             sb.append(")");
         }
-        if (!didOne) sb.append("No activity");
+        if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
         
         // Calculate wakelock times across all uids.
@@ -1916,24 +1974,27 @@
         long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
         long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
 
+        if (fullWakeLockTimeTotalMicros != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
+                            (fullWakeLockTimeTotalMicros + 500) / 1000);
+            pw.println(sb.toString());
+        }
+
+        if (partialWakeLockTimeTotalMicros != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
+                            (partialWakeLockTimeTotalMicros + 500) / 1000);
+            pw.println(sb.toString());
+        }
+
         pw.print(prefix);
                 pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
                 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
                 pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
                 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
-        pw.print(prefix);
-                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
-                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
-                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
-                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
-        sb.setLength(0);
-        sb.append(prefix);
-                sb.append("  Total full wakelock time: "); formatTimeMs(sb,
-                        (fullWakeLockTimeTotalMicros + 500) / 1000);
-                sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
-                        (partialWakeLockTimeTotalMicros + 500) / 1000);
-        pw.println(sb.toString());
-        
         sb.setLength(0);
         sb.append(prefix);
         sb.append("  Signal levels:");
@@ -1944,6 +2005,7 @@
                 continue;
             }
             sb.append("\n    ");
+            sb.append(prefix);
             didOne = true;
             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
             sb.append(" ");
@@ -1960,7 +2022,7 @@
         sb.setLength(0);
         sb.append(prefix);
         sb.append("  Signal scanning time: ");
-        formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
+        formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
         pw.println(sb.toString());
 
         sb.setLength(0);
@@ -1973,6 +2035,7 @@
                 continue;
             }
             sb.append("\n    ");
+            sb.append(prefix);
             didOne = true;
             sb.append(DATA_CONNECTION_NAMES[i]);
             sb.append(" ");
@@ -1989,9 +2052,31 @@
         sb.setLength(0);
         sb.append(prefix);
         sb.append("  Mobile radio active time: ");
-        formatTimeMs(sb, getMobileRadioActiveTime(batteryRealtime, which) / 1000);
+        final long mobileActiveTime = getMobileRadioActiveTime(batteryRealtime, which);
+        formatTimeMs(sb, mobileActiveTime / 1000);
+        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
+        sb.append(") "); sb.append(getMobileRadioActiveCount(which));
+        sb.append("x");
         pw.println(sb.toString());
 
+        final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
+        if (mobileActiveUnknownTime != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("  Mobile radio active unknown time: ");
+            formatTimeMs(sb, mobileActiveUnknownTime / 1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
+            sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
+            sb.append("x");
+            pw.println(sb.toString());
+        }
+
+        pw.print(prefix);
+                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
+                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
+                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
+                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
         sb.setLength(0);
         sb.append(prefix);
                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
@@ -2128,7 +2213,8 @@
                         pw.println();
                         break;
                     case APP:
-                        pw.print(prefix); pw.print("    Uid "); pw.print(bs.uidObj.getUid());
+                        pw.print(prefix); pw.print("    Uid ");
+                        UserHandle.formatUid(pw, bs.uidObj.getUid());
                         pw.print(": "); printmAh(pw, bs.value); pw.println();
                         break;
                     case USER:
@@ -2148,6 +2234,32 @@
             pw.println();
         }
 
+        sippers = helper.getMobilemsppList();
+        if (sippers != null && sippers.size() > 0) {
+            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
+            long totalTime = 0;
+            for (int i=0; i<sippers.size(); i++) {
+                BatterySipper bs = sippers.get(i);
+                sb.setLength(0);
+                sb.append(prefix); sb.append("    Uid ");
+                UserHandle.formatUid(sb, bs.uidObj.getUid());
+                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
+                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
+                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
+                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
+                pw.println(sb.toString());
+                totalTime += bs.mobileActive;
+            }
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("    TOTAL TIME: ");
+            formatTimeMs(sb, totalTime);
+            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
+            sb.append(")");
+            pw.println(sb.toString());
+            pw.println();
+        }
+
         if (timers.size() > 0) {
             Collections.sort(timers, timerComparator);
             pw.print(prefix); pw.println("  All partial wake locks:");
@@ -2179,13 +2291,15 @@
             UserHandle.formatUid(pw, uid);
             pw.println(":");
             boolean uidActivity = false;
-            
+
             long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
             long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
             long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
             long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
             long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
             long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+            long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
+            int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
             long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
             long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
@@ -2200,6 +2314,23 @@
                         pw.print(" sent (packets "); pw.print(mobileRxPackets);
                         pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
             }
+            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
+                sb.setLength(0);
+                sb.append(prefix); sb.append("    Mobile radio active: ");
+                formatTimeMs(sb, uidMobileActiveTime / 1000);
+                sb.append("(");
+                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
+                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
+                long packets = mobileRxPackets + mobileTxPackets;
+                if (packets == 0) {
+                    packets = 1;
+                }
+                sb.append(" @ ");
+                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
+                sb.append(" mspp");
+                pw.println(sb.toString());
+            }
+
             if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
                 pw.print(prefix); pw.print("    Wi-Fi network: ");
                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
@@ -2208,6 +2339,24 @@
                         pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
             }
 
+            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
+                    || uidWifiRunningTime != 0) {
+                sb.setLength(0);
+                sb.append(prefix); sb.append("    Wifi Running: ");
+                        formatTimeMs(sb, uidWifiRunningTime / 1000);
+                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
+                                whichBatteryRealtime)); sb.append(")\n");
+                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
+                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
+                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
+                                whichBatteryRealtime)); sb.append(")\n");
+                sb.append(prefix); sb.append("    Wifi Scan: ");
+                        formatTimeMs(sb, wifiScanTime / 1000);
+                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
+                                whichBatteryRealtime)); sb.append(")");
+                pw.println(sb.toString());
+            }
+
             if (u.hasUserActivity()) {
                 boolean hasData = false;
                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
@@ -2229,24 +2378,6 @@
                     pw.println(sb.toString());
                 }
             }
-            
-            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
-                    || uidWifiRunningTime != 0) {
-                sb.setLength(0);
-                sb.append(prefix); sb.append("    Wifi Running: ");
-                        formatTimeMs(sb, uidWifiRunningTime / 1000);
-                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
-                                whichBatteryRealtime)); sb.append(")\n");
-                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
-                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
-                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
-                                whichBatteryRealtime)); sb.append(")\n");
-                sb.append(prefix); sb.append("    Wifi Scan: ");
-                        formatTimeMs(sb, wifiScanTime / 1000);
-                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
-                                whichBatteryRealtime)); sb.append(")");
-                pw.println(sb.toString());
-            }
 
             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
             if (wakelocks.size() > 0) {
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java
index 96dc61a..70dcdd8 100644
--- a/core/java/android/os/Broadcaster.java
+++ b/core/java/android/os/Broadcaster.java
@@ -171,10 +171,10 @@
     public void broadcast(Message msg)
     {
         synchronized (this) {
-        	if (mReg == null) {
-        		return;
-        	}
-        	
+            if (mReg == null) {
+                return;
+            }
+            
             int senderWhat = msg.what;
             Registration start = mReg;
             Registration r = start;
diff --git a/media/java/android/media/MediaSessionToken.aidl b/core/java/android/os/INetworkActivityListener.aidl
similarity index 76%
copy from media/java/android/media/MediaSessionToken.aidl
copy to core/java/android/os/INetworkActivityListener.aidl
index e2f1abc..24e6e55 100644
--- a/media/java/android/media/MediaSessionToken.aidl
+++ b/core/java/android/os/INetworkActivityListener.aidl
@@ -1,4 +1,4 @@
-/* Copyright 2014, The Android Open Source Project
+/* Copyright 2013, 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.
@@ -13,6 +13,12 @@
 ** limitations under the License.
 */
 
-package android.media;
+package android.os;
 
-parcelable MediaSessionToken;
+/**
+ * @hide
+ */
+oneway interface INetworkActivityListener
+{
+    void onNetworkActive();
+}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 21b8ae5..e6a4c5a 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -23,6 +23,7 @@
 import android.net.NetworkStats;
 import android.net.RouteInfo;
 import android.net.wifi.WifiConfiguration;
+import android.os.INetworkActivityListener;
 
 /**
  * @hide
@@ -306,14 +307,12 @@
      * reference-counting if an idletimer already exists for given
      * {@code iface}.
      *
-     * {@code label} usually represents the network type of {@code iface}.
-     * Caller should ensure that {@code label} for an {@code iface} remains the
-     * same for all calls to addIdleTimer.
+     * {@code type} is the type of the interface, such as TYPE_MOBILE.
      *
      * Every {@code addIdleTimer} should be paired with a
      * {@link removeIdleTimer} to cleanup when the network disconnects.
      */
-    void addIdleTimer(String iface, int timeout, String label);
+    void addIdleTimer(String iface, int timeout, int type);
 
     /**
      * Removes idletimer for an interface.
@@ -441,4 +440,19 @@
      * Determine whether the clatd (464xlat) service has been started
      */
     boolean isClatdStarted();
+
+    /**
+     * Start listening for mobile activity state changes.
+     */
+    void registerNetworkActivityListener(INetworkActivityListener listener);
+
+    /**
+     * Stop listening for mobile activity state changes.
+     */
+    void unregisterNetworkActivityListener(INetworkActivityListener listener);
+
+    /**
+     * Check whether the mobile radio is currently active.
+     */
+    boolean isNetworkActive();
 }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 56176a4..069285a 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -25,8 +25,10 @@
 {
     // WARNING: The first four methods must remain the first three methods because their
     // transaction numbers must not change unless IPowerManager.cpp is also updated.
-    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws);
-    void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, int uidtoblame);
+    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws,
+            String historyTag);
+    void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName,
+            int uidtoblame);
     void releaseWakeLock(IBinder lock, int flags);
     void updateWakeLockUids(IBinder lock, in int[] uids);
 
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index ff31130..6d7c9cf 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -149,7 +149,7 @@
                         + msg.callback + " what=" + msg.what);
             }
 
-            msg.recycle();
+            msg.recycleUnchecked();
         }
     }
 
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 51203a48..d30bbc1 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -71,7 +71,14 @@
      */
     public Messenger replyTo;
 
-    /** If set message is in use */
+    /** If set message is in use.
+     * This flag is set when the message is enqueued and remains set while it
+     * is delivered and afterwards when it is recycled.  The flag is only cleared
+     * when a new message is created or obtained since that is the only time that
+     * applications are allowed to modify the contents of the message.
+     *
+     * It is an error to attempt to enqueue or recycle a message that is already in use.
+     */
     /*package*/ static final int FLAG_IN_USE = 1 << 0;
 
     /** If set message is asynchronous */
@@ -86,9 +93,9 @@
     
     /*package*/ Bundle data;
     
-    /*package*/ Handler target;     
+    /*package*/ Handler target;
     
-    /*package*/ Runnable callback;   
+    /*package*/ Runnable callback;
     
     // sometimes we store linked lists of these things
     /*package*/ Message next;
@@ -109,6 +116,7 @@
                 Message m = sPool;
                 sPool = m.next;
                 m.next = null;
+                m.flags = 0; // clear in-use flag
                 sPoolSize--;
                 return m;
             }
@@ -241,12 +249,38 @@
     }
 
     /**
-     * Return a Message instance to the global pool.  You MUST NOT touch
-     * the Message after calling this function -- it has effectively been
-     * freed.
+     * Return a Message instance to the global pool.
+     * <p>
+     * You MUST NOT touch the Message after calling this function because it has
+     * effectively been freed.  It is an error to recycle a message that is currently
+     * enqueued or that is in the process of being delivered to a Handler.
+     * </p>
      */
     public void recycle() {
-        clearForRecycle();
+        if (isInUse()) {
+            throw new IllegalStateException("This message cannot be recycled because it "
+                    + "is still in use.");
+        }
+        recycleUnchecked();
+    }
+
+    /**
+     * Recycles a Message that may be in-use.
+     * Used internally by the MessageQueue and Looper when disposing of queued Messages.
+     */
+    void recycleUnchecked() {
+        // Mark the message as in use while it remains in the recycled object pool.
+        // Clear out all other details.
+        flags = FLAG_IN_USE;
+        what = 0;
+        arg1 = 0;
+        arg2 = 0;
+        obj = null;
+        replyTo = null;
+        when = 0;
+        target = null;
+        callback = null;
+        data = null;
 
         synchronized (sPoolSync) {
             if (sPoolSize < MAX_POOL_SIZE) {
@@ -402,19 +436,6 @@
         }
     }
 
-    /*package*/ void clearForRecycle() {
-        flags = 0;
-        what = 0;
-        arg1 = 0;
-        arg2 = 0;
-        obj = null;
-        replyTo = null;
-        when = 0;
-        target = null;
-        callback = null;
-        data = null;
-    }
-
     /*package*/ boolean isInUse() {
         return ((flags & FLAG_IN_USE) == FLAG_IN_USE);
     }
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 7ca5d49..01a23ce 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.util.AndroidRuntimeException;
 import android.util.Log;
 import android.util.Printer;
 
@@ -169,7 +168,6 @@
                         }
                         msg.next = null;
                         if (false) Log.v("MessageQueue", "Returning message: " + msg);
-                        msg.markInUse();
                         return msg;
                     }
                 } else {
@@ -233,7 +231,7 @@
 
     void quit(boolean safe) {
         if (!mQuitAllowed) {
-            throw new RuntimeException("Main thread not allowed to quit.");
+            throw new IllegalStateException("Main thread not allowed to quit.");
         }
 
         synchronized (this) {
@@ -259,6 +257,7 @@
         synchronized (this) {
             final int token = mNextBarrierToken++;
             final Message msg = Message.obtain();
+            msg.markInUse();
             msg.when = when;
             msg.arg1 = token;
 
@@ -303,7 +302,7 @@
                 mMessages = p.next;
                 needWake = mMessages == null || mMessages.target != null;
             }
-            p.recycle();
+            p.recycleUnchecked();
 
             // If the loop is quitting then it is already awake.
             // We can assume mPtr != 0 when mQuitting is false.
@@ -314,21 +313,23 @@
     }
 
     boolean enqueueMessage(Message msg, long when) {
-        if (msg.isInUse()) {
-            throw new AndroidRuntimeException(msg + " This message is already in use.");
-        }
         if (msg.target == null) {
-            throw new AndroidRuntimeException("Message must have a target.");
+            throw new IllegalArgumentException("Message must have a target.");
+        }
+        if (msg.isInUse()) {
+            throw new IllegalStateException(msg + " This message is already in use.");
         }
 
         synchronized (this) {
             if (mQuitting) {
-                RuntimeException e = new RuntimeException(
+                IllegalStateException e = new IllegalStateException(
                         msg.target + " sending message to a Handler on a dead thread");
                 Log.w("MessageQueue", e.getMessage(), e);
+                msg.recycle();
                 return false;
             }
 
+            msg.markInUse();
             msg.when = when;
             Message p = mMessages;
             boolean needWake;
@@ -424,7 +425,7 @@
                    && (object == null || p.obj == object)) {
                 Message n = p.next;
                 mMessages = n;
-                p.recycle();
+                p.recycleUnchecked();
                 p = n;
             }
 
@@ -435,7 +436,7 @@
                     if (n.target == h && n.what == what
                         && (object == null || n.obj == object)) {
                         Message nn = n.next;
-                        n.recycle();
+                        n.recycleUnchecked();
                         p.next = nn;
                         continue;
                     }
@@ -458,7 +459,7 @@
                    && (object == null || p.obj == object)) {
                 Message n = p.next;
                 mMessages = n;
-                p.recycle();
+                p.recycleUnchecked();
                 p = n;
             }
 
@@ -469,7 +470,7 @@
                     if (n.target == h && n.callback == r
                         && (object == null || n.obj == object)) {
                         Message nn = n.next;
-                        n.recycle();
+                        n.recycleUnchecked();
                         p.next = nn;
                         continue;
                     }
@@ -492,7 +493,7 @@
                     && (object == null || p.obj == object)) {
                 Message n = p.next;
                 mMessages = n;
-                p.recycle();
+                p.recycleUnchecked();
                 p = n;
             }
 
@@ -502,7 +503,7 @@
                 if (n != null) {
                     if (n.target == h && (object == null || n.obj == object)) {
                         Message nn = n.next;
-                        n.recycle();
+                        n.recycleUnchecked();
                         p.next = nn;
                         continue;
                     }
@@ -516,7 +517,7 @@
         Message p = mMessages;
         while (p != null) {
             Message n = p.next;
-            p.recycle();
+            p.recycleUnchecked();
             p = n;
         }
         mMessages = null;
@@ -544,7 +545,7 @@
                 do {
                     p = n;
                     n = p.next;
-                    p.recycle();
+                    p.recycleUnchecked();
                 } while (n != null);
             }
         }
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 4d4c337..74ca3bb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -662,6 +662,7 @@
         private boolean mRefCounted = true;
         private boolean mHeld;
         private WorkSource mWorkSource;
+        private String mHistoryTag;
 
         private final Runnable mReleaser = new Runnable() {
             public void run() {
@@ -748,7 +749,8 @@
                 // been explicitly released by the keyguard.
                 mHandler.removeCallbacks(mReleaser);
                 try {
-                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);
+                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
+                            mHistoryTag);
                 } catch (RemoteException e) {
                 }
                 mHeld = true;
@@ -855,6 +857,11 @@
         }
 
         /** @hide */
+        public void setHistoryTag(String tag) {
+            mHistoryTag = tag;
+        }
+
+        /** @hide */
         public void setUnimportantForLogging(boolean state) {
             if (state) mFlags |= UNIMPORTANT_FOR_LOGGING;
             else mFlags &= ~UNIMPORTANT_FOR_LOGGING;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 8f6dda1..1ec5cd5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -164,11 +164,13 @@
 
     /**
      * Returns whether the system supports multiple users.
-     * @return true if multiple users can be created, false if it is a single user device.
+     * @return true if multiple users can be created by user, false if it is a single user device.
      * @hide
      */
     public static boolean supportsMultipleUsers() {
-        return getMaxSupportedUsers() > 1;
+        return getMaxSupportedUsers() > 1
+                && SystemProperties.getBoolean("fw.show_multiuserui",
+                Resources.getSystem().getBoolean(R.bool.config_enableMultiUserUI));
     }
 
     /**
@@ -601,6 +603,26 @@
     }
 
     /**
+     * Returns true if the user switcher should be shown, this will be if there
+     * are multiple users that aren't managed profiles.
+     * @hide
+     * @return true if user switcher should be shown.
+     */
+    public boolean isUserSwitcherEnabled() {
+        List<UserInfo> users = getUsers(true);
+        if (users == null) {
+           return false;
+        }
+        int switchableUserCount = 0;
+        for (UserInfo user : users) {
+            if (user.supportsSwitchTo()) {
+                ++switchableUserCount;
+            }
+        }
+        return switchableUserCount > 1;
+    }
+
+    /**
      * Returns a serial number on this device for a given userHandle. User handles can be recycled
      * when deleting and creating users, but serial numbers are not reused until the device is wiped.
      * @param userHandle
diff --git a/core/java/android/preference/GenericInflater.java b/core/java/android/preference/GenericInflater.java
index 3003290..7de7d1c 100644
--- a/core/java/android/preference/GenericInflater.java
+++ b/core/java/android/preference/GenericInflater.java
@@ -191,7 +191,7 @@
     public void setFactory(Factory<T> factory) {
         if (mFactorySet) {
             throw new IllegalStateException("" +
-            		"A factory has already been set on this inflater");
+                    "A factory has already been set on this inflater");
         }
         if (factory == null) {
             throw new NullPointerException("Given factory can not be null");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 18018e2..7777334 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -749,6 +749,14 @@
     public static final String ACTION_PRINT_SETTINGS =
             "android.settings.ACTION_PRINT_SETTINGS";
 
+    /**
+     * Activity Action: Show Zen Mode configuration settings.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ZEN_MODE_SETTINGS = "android.settings.ZEN_MODE_SETTINGS";
+
     // End of Intent actions for Settings
 
     /**
@@ -3352,21 +3360,29 @@
         public static final String INSTALL_NON_MARKET_APPS = Global.INSTALL_NON_MARKET_APPS;
 
         /**
-         * Comma-separated list of location providers that activities may access.
+         * Comma-separated list of location providers that activities may access. Do not rely on
+         * this value being present in settings.db or on ContentObserver notifications on the
+         * corresponding Uri.
          *
-         * @deprecated use {@link #LOCATION_MODE}
+         * @deprecated use {@link #LOCATION_MODE} and
+         * {@link LocationManager#MODE_CHANGED_ACTION} (or
+         * {@link LocationManager#PROVIDERS_CHANGED_ACTION})
          */
         @Deprecated
         public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
 
         /**
          * The degree of location access enabled by the user.
-         * <p/>
+         * <p>
          * When used with {@link #putInt(ContentResolver, String, int)}, must be one of {@link
          * #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, {@link
          * #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. When used with {@link
          * #getInt(ContentResolver, String)}, the caller must gracefully handle additional location
          * modes that might be added in the future.
+         * <p>
+         * Note: do not rely on this value being present in settings.db or on ContentObserver
+         * notifications for the corresponding Uri. Use {@link LocationManager#MODE_CHANGED_ACTION}
+         * to receive changes in this value.
          */
         public static final String LOCATION_MODE = "location_mode";
 
@@ -6082,6 +6098,35 @@
                 "lock_screen_show_notifications";
 
         /**
+         * Defines global zen mode.  One of ZEN_MODE_OFF, ZEN_MODE_LIMITED, ZEN_MODE_FULL.
+         *
+         * @hide
+         */
+        public static final String ZEN_MODE = "zen_mode";
+
+        /** @hide */ public static final int ZEN_MODE_OFF = 0;
+        /** @hide */ public static final int ZEN_MODE_LIMITED = 1;
+        /** @hide */ public static final int ZEN_MODE_FULL = 2;
+
+        /** @hide */ public static String zenModeToString(int mode) {
+            if (mode == ZEN_MODE_OFF) return "ZEN_MODE_OFF";
+            if (mode == ZEN_MODE_LIMITED) return "ZEN_MODE_LIMITED";
+            if (mode == ZEN_MODE_FULL) return "ZEN_MODE_FULL";
+            throw new IllegalArgumentException("Invalid zen mode: " + mode);
+        }
+
+        /**
+         * Defines global heads up toggle.  One of HEADS_UP_OFF, HEADS_UP_ON.
+         *
+         * @hide
+         */
+        public static final String HEADS_UP_NOTIFICATIONS_ENABLED =
+                "heads_up_notifications_enabled";
+
+        /** @hide */ public static final int HEADS_UP_OFF = 0;
+        /** @hide */ public static final int HEADS_UP_ON = 1;
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java
index 580a369..cda8015 100644
--- a/core/java/android/text/style/BackgroundColorSpan.java
+++ b/core/java/android/text/style/BackgroundColorSpan.java
@@ -26,9 +26,9 @@
 
     private final int mColor;
 
-	public BackgroundColorSpan(int color) {
-		mColor = color;
-	}
+    public BackgroundColorSpan(int color) {
+        mColor = color;
+    }
 
     public BackgroundColorSpan(Parcel src) {
         mColor = src.readInt();
@@ -46,12 +46,12 @@
         dest.writeInt(mColor);
     }
 
-	public int getBackgroundColor() {
-		return mColor;
-	}
+    public int getBackgroundColor() {
+        return mColor;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.bgColor = mColor;
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.bgColor = mColor;
+    }
 }
diff --git a/core/java/android/text/style/CharacterStyle.java b/core/java/android/text/style/CharacterStyle.java
index 14dfddd..5b95f1a 100644
--- a/core/java/android/text/style/CharacterStyle.java
+++ b/core/java/android/text/style/CharacterStyle.java
@@ -24,7 +24,7 @@
  * ones may just implement {@link UpdateAppearance}.
  */
 public abstract class CharacterStyle {
-	public abstract void updateDrawState(TextPaint tp);
+    public abstract void updateDrawState(TextPaint tp);
 
     /**
      * A given CharacterStyle can only applied to a single region of a given
diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java
index 476124d..c9e09bd 100644
--- a/core/java/android/text/style/ForegroundColorSpan.java
+++ b/core/java/android/text/style/ForegroundColorSpan.java
@@ -26,9 +26,9 @@
 
     private final int mColor;
 
-	public ForegroundColorSpan(int color) {
-		mColor = color;
-	}
+    public ForegroundColorSpan(int color) {
+        mColor = color;
+    }
 
     public ForegroundColorSpan(Parcel src) {
         mColor = src.readInt();
@@ -46,12 +46,12 @@
         dest.writeInt(mColor);
     }
 
-	public int getForegroundColor() {
-		return mColor;
-	}
+    public int getForegroundColor() {
+        return mColor;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setColor(mColor);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setColor(mColor);
+    }
 }
diff --git a/core/java/android/text/style/MaskFilterSpan.java b/core/java/android/text/style/MaskFilterSpan.java
index 64ab0d8..2ff52a8 100644
--- a/core/java/android/text/style/MaskFilterSpan.java
+++ b/core/java/android/text/style/MaskFilterSpan.java
@@ -21,18 +21,18 @@
 
 public class MaskFilterSpan extends CharacterStyle implements UpdateAppearance {
 
-	private MaskFilter mFilter;
+    private MaskFilter mFilter;
 
-	public MaskFilterSpan(MaskFilter filter) {
-		mFilter = filter;
-	}
+    public MaskFilterSpan(MaskFilter filter) {
+        mFilter = filter;
+    }
 
-	public MaskFilter getMaskFilter() {
-		return mFilter;
-	}
+    public MaskFilter getMaskFilter() {
+        return mFilter;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setMaskFilter(mFilter);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setMaskFilter(mFilter);
+    }
 }
diff --git a/core/java/android/text/style/MetricAffectingSpan.java b/core/java/android/text/style/MetricAffectingSpan.java
index a02b276..853ecc6 100644
--- a/core/java/android/text/style/MetricAffectingSpan.java
+++ b/core/java/android/text/style/MetricAffectingSpan.java
@@ -26,7 +26,7 @@
 extends CharacterStyle
 implements UpdateLayout {
 
-	public abstract void updateMeasureState(TextPaint p);
+    public abstract void updateMeasureState(TextPaint p);
 
     /**
      * Returns "this" for most MetricAffectingSpans, but for 
diff --git a/core/java/android/text/style/RasterizerSpan.java b/core/java/android/text/style/RasterizerSpan.java
index 75b5bcc..cae9640 100644
--- a/core/java/android/text/style/RasterizerSpan.java
+++ b/core/java/android/text/style/RasterizerSpan.java
@@ -21,18 +21,18 @@
 
 public class RasterizerSpan extends CharacterStyle implements UpdateAppearance {
 
-	private Rasterizer mRasterizer;
+    private Rasterizer mRasterizer;
 
-	public RasterizerSpan(Rasterizer r) {
-		mRasterizer = r;
-	}
+    public RasterizerSpan(Rasterizer r) {
+        mRasterizer = r;
+    }
 
-	public Rasterizer getRasterizer() {
-		return mRasterizer;
-	}
+    public Rasterizer getRasterizer() {
+        return mRasterizer;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setRasterizer(mRasterizer);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setRasterizer(mRasterizer);
+    }
 }
diff --git a/core/java/android/text/style/RelativeSizeSpan.java b/core/java/android/text/style/RelativeSizeSpan.java
index 9717362..632dbd4 100644
--- a/core/java/android/text/style/RelativeSizeSpan.java
+++ b/core/java/android/text/style/RelativeSizeSpan.java
@@ -23,11 +23,11 @@
 
 public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final float mProportion;
+    private final float mProportion;
 
-	public RelativeSizeSpan(float proportion) {
-		mProportion = proportion;
-	}
+    public RelativeSizeSpan(float proportion) {
+        mProportion = proportion;
+    }
 
     public RelativeSizeSpan(Parcel src) {
         mProportion = src.readFloat();
@@ -45,17 +45,17 @@
         dest.writeFloat(mProportion);
     }
 
-	public float getSizeChange() {
-		return mProportion;
-	}
+    public float getSizeChange() {
+        return mProportion;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setTextSize(ds.getTextSize() * mProportion);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setTextSize(ds.getTextSize() * mProportion);
+    }
 
-	@Override
-	public void updateMeasureState(TextPaint ds) {
-		ds.setTextSize(ds.getTextSize() * mProportion);
-	}
+    @Override
+    public void updateMeasureState(TextPaint ds) {
+        ds.setTextSize(ds.getTextSize() * mProportion);
+    }
 }
diff --git a/core/java/android/text/style/ScaleXSpan.java b/core/java/android/text/style/ScaleXSpan.java
index 655064b..a22a5a1 100644
--- a/core/java/android/text/style/ScaleXSpan.java
+++ b/core/java/android/text/style/ScaleXSpan.java
@@ -23,11 +23,11 @@
 
 public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final float mProportion;
+    private final float mProportion;
 
-	public ScaleXSpan(float proportion) {
-		mProportion = proportion;
-	}
+    public ScaleXSpan(float proportion) {
+        mProportion = proportion;
+    }
 
     public ScaleXSpan(Parcel src) {
         mProportion = src.readFloat();
@@ -45,17 +45,17 @@
         dest.writeFloat(mProportion);
     }
 
-	public float getScaleX() {
-		return mProportion;
-	}
+    public float getScaleX() {
+        return mProportion;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setTextScaleX(ds.getTextScaleX() * mProportion);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+    }
 
-	@Override
-	public void updateMeasureState(TextPaint ds) {
-		ds.setTextScaleX(ds.getTextScaleX() * mProportion);
-	}
+    @Override
+    public void updateMeasureState(TextPaint ds) {
+        ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+    }
 }
diff --git a/core/java/android/text/style/StrikethroughSpan.java b/core/java/android/text/style/StrikethroughSpan.java
index b51363a..303e41574 100644
--- a/core/java/android/text/style/StrikethroughSpan.java
+++ b/core/java/android/text/style/StrikethroughSpan.java
@@ -40,8 +40,8 @@
     public void writeToParcel(Parcel dest, int flags) {
     }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setStrikeThruText(true);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setStrikeThruText(true);
+    }
 }
diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java
index 8e6147c..b08f70e 100644
--- a/core/java/android/text/style/StyleSpan.java
+++ b/core/java/android/text/style/StyleSpan.java
@@ -33,17 +33,17 @@
  */
 public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final int mStyle;
+    private final int mStyle;
 
-	/**
-	 * 
-	 * @param style An integer constant describing the style for this span. Examples
-	 * include bold, italic, and normal. Values are constants defined 
-	 * in {@link android.graphics.Typeface}.
-	 */
-	public StyleSpan(int style) {
-		mStyle = style;
-	}
+    /**
+     * 
+     * @param style An integer constant describing the style for this span. Examples
+     * include bold, italic, and normal. Values are constants defined 
+     * in {@link android.graphics.Typeface}.
+     */
+    public StyleSpan(int style) {
+        mStyle = style;
+    }
 
     public StyleSpan(Parcel src) {
         mStyle = src.readInt();
@@ -61,19 +61,19 @@
         dest.writeInt(mStyle);
     }
 
-	/**
-	 * Returns the style constant defined in {@link android.graphics.Typeface}. 
-	 */
-	public int getStyle() {
-		return mStyle;
-	}
+    /**
+     * Returns the style constant defined in {@link android.graphics.Typeface}. 
+     */
+    public int getStyle() {
+        return mStyle;
+    }
 
-	@Override
+    @Override
     public void updateDrawState(TextPaint ds) {
         apply(ds, mStyle);
     }
 
-	@Override
+    @Override
     public void updateMeasureState(TextPaint paint) {
         apply(paint, mStyle);
     }
diff --git a/core/java/android/text/style/UnderlineSpan.java b/core/java/android/text/style/UnderlineSpan.java
index b0cb0e8..80b2427 100644
--- a/core/java/android/text/style/UnderlineSpan.java
+++ b/core/java/android/text/style/UnderlineSpan.java
@@ -40,8 +40,8 @@
     public void writeToParcel(Parcel dest, int flags) {
     }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setUnderlineText(true);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setUnderlineText(true);
+    }
 }
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index fd3f9b3..9f1e72d 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -552,8 +552,7 @@
         return false;
     }
 
-    /** @hide */
-    public static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
+    private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
         ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
         if (runningAnimators == null) {
             runningAnimators = new ArrayMap<Animator, AnimationInfo>();
@@ -1113,30 +1112,32 @@
                 }
             }
         }
-        TransitionValues values = new TransitionValues();
-        values.view = view;
-        if (start) {
-            captureStartValues(values);
-        } else {
-            captureEndValues(values);
-        }
-        if (start) {
-            if (!isListViewItem) {
-                mStartValues.viewValues.put(view, values);
-                if (id >= 0) {
-                    mStartValues.idValues.put((int) id, values);
-                }
+        if (view.getParent() instanceof ViewGroup) {
+            TransitionValues values = new TransitionValues();
+            values.view = view;
+            if (start) {
+                captureStartValues(values);
             } else {
-                mStartValues.itemIdValues.put(itemId, values);
+                captureEndValues(values);
             }
-        } else {
-            if (!isListViewItem) {
-                mEndValues.viewValues.put(view, values);
-                if (id >= 0) {
-                    mEndValues.idValues.put((int) id, values);
+            if (start) {
+                if (!isListViewItem) {
+                    mStartValues.viewValues.put(view, values);
+                    if (id >= 0) {
+                        mStartValues.idValues.put((int) id, values);
+                    }
+                } else {
+                    mStartValues.itemIdValues.put(itemId, values);
                 }
             } else {
-                mEndValues.itemIdValues.put(itemId, values);
+                if (!isListViewItem) {
+                    mEndValues.viewValues.put(view, values);
+                    if (id >= 0) {
+                        mEndValues.idValues.put((int) id, values);
+                    }
+                } else {
+                    mEndValues.itemIdValues.put(itemId, values);
+                }
             }
         }
         if (view instanceof ViewGroup) {
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 9fa554c..912f2ed 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -285,46 +285,27 @@
                 com.android.internal.R.styleable.TransitionManager);
         int transitionId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_transition, -1);
-        Scene fromScene = null, toScene = null;
         int fromId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_fromScene, -1);
-        if (fromId >= 0) fromScene = Scene.getSceneForLayout(sceneRoot, fromId, mContext);
+        Scene fromScene = (fromId < 0) ? null: Scene.getSceneForLayout(sceneRoot, fromId, mContext);
         int toId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_toScene, -1);
-        if (toId >= 0) toScene = Scene.getSceneForLayout(sceneRoot, toId, mContext);
-        String fromName = a.getString(
-                com.android.internal.R.styleable.TransitionManager_fromSceneName);
-        String toName = a.getString(
-                com.android.internal.R.styleable.TransitionManager_toSceneName);
+        Scene toScene = (toId < 0) ? null : Scene.getSceneForLayout(sceneRoot, toId, mContext);
+
         if (transitionId >= 0) {
             Transition transition = inflateTransition(transitionId);
             if (transition != null) {
-                if (fromScene != null) {
-                    boolean hasDest = false;
-                    if (toScene != null) {
-                        transitionManager.setTransition(fromScene, toScene, transition);
-                        hasDest = true;
-                    }
-
-                    if (!TextUtils.isEmpty(toName)) {
-                        transitionManager.setTransition(fromScene, toName, transition);
-                        hasDest = true;
-                    }
-
-                    if (!hasDest) {
-                        throw new RuntimeException("No matching toScene or toSceneName for given " +
-                                "fromScene for transition ID " + transitionId);
-                    }
-                } else if (toId >= 0) {
-                    transitionManager.setTransition(toScene, transition);
-                }
-                if (fromName != null) {
-                    if (toScene != null) {
-                        transitionManager.setTransition(fromName, toScene, transition);
-                    } else {
-                        throw new RuntimeException("No matching toScene for given fromSceneName " +
+                if (fromScene == null) {
+                    if (toScene == null) {
+                        throw new RuntimeException("No matching fromScene or toScene " +
                                 "for transition ID " + transitionId);
+                    } else {
+                        transitionManager.setTransition(toScene, transition);
                     }
+                } else if (toScene == null) {
+                    transitionManager.setExitTransition(fromScene, transition);
+                } else {
+                    transitionManager.setTransition(fromScene, toScene, transition);
                 }
             }
         }
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 0106f7fb..f3abfb0 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -70,12 +70,9 @@
     private static final String[] EMPTY_STRINGS = new String[0];
 
     ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
+    ArrayMap<Scene, Transition> mExitSceneTransitions = new ArrayMap<Scene, Transition>();
     ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
             new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
-    ArrayMap<Scene, ArrayMap<String, Transition>> mSceneNameTransitions =
-            new ArrayMap<Scene, ArrayMap<String, Transition>>();
-    ArrayMap<String, ArrayMap<Scene, Transition>> mNameSceneTransitions =
-            new ArrayMap<String, ArrayMap<Scene, Transition>>();
     private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
             sRunningTransitions =
             new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
@@ -122,6 +119,21 @@
     }
 
     /**
+     * Sets a specific transition to occur when the given scene is exited. This
+     * has the lowest priority -- if a Scene-to-Scene transition or
+     * Scene enter transition can be applied, it will.
+     *
+     * @param scene The scene which, when exited, will cause the given
+     * transition to run.
+     * @param transition The transition that will play when the given scene is
+     * exited. A value of null will result in the default behavior of
+     * using the default transition instead.
+     */
+    public void setExitTransition(Scene scene, Transition transition) {
+        mExitSceneTransitions.put(scene, transition);
+    }
+
+    /**
      * Sets a specific transition to occur when the given pair of scenes is
      * exited/entered.
      *
@@ -169,6 +181,9 @@
             }
         }
         transition = mSceneTransitions.get(scene);
+        if (transition == null && sceneRoot != null) {
+            transition = mExitSceneTransitions.get(Scene.getCurrentScene(sceneRoot));
+        }
         return (transition != null) ? transition : sDefaultTransition;
     }
 
@@ -224,138 +239,31 @@
     }
 
     /**
-     * Retrieve the transition from a named scene to a target defined scene if one has been
+     * Retrieve the transition to a target defined scene if one has been
      * associated with this TransitionManager.
      *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromName Named scene that this transition corresponds to
      * @param toScene Target scene that this transition will move to
-     * @return Transition corresponding to the given fromName and toScene or null
+     * @return Transition corresponding to the given toScene or null
      *         if no association exists in this TransitionManager
      *
-     * @see #setTransition(String, Scene, Transition)
+     * @see #setTransition(Scene, Transition)
+     * @hide
      */
-    public Transition getNamedTransition(String fromName, Scene toScene) {
-        ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
-        if (m != null) {
-            return m.get(toScene);
-        }
-        return null;
+    public Transition getEnterTransition(Scene toScene) {
+        return mSceneTransitions.get(toScene);
     }
 
     /**
      * Retrieve the transition from a defined scene to a target named scene if one has been
      * associated with this TransitionManager.
      *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
      * @param fromScene Scene that this transition starts from
-     * @param toName Name of the target scene
-     * @return Transition corresponding to the given fromScene and toName or null
+     * @return Transition corresponding to the given fromScene or null
      *         if no association exists in this TransitionManager
+     * @hide
      */
-    public Transition getNamedTransition(Scene fromScene, String toName) {
-        ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
-        if (m != null) {
-            return m.get(toName);
-        }
-        return null;
-    }
-
-    /**
-     * Retrieve the supported target named scenes when transitioning away from the given scene.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromScene Scene to transition from
-     * @return An array of Strings naming each supported transition starting from
-     *         <code>fromScene</code>. If no transitions to a named scene from the given
-     *         scene are supported this function will return a String[] of length 0.
-     *
-     * @see #setTransition(Scene, String, Transition)
-     */
-    public String[] getTargetSceneNames(Scene fromScene) {
-        final ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
-        if (m == null) {
-            return EMPTY_STRINGS;
-        }
-        final int count = m.size();
-        final String[] result = new String[count];
-        for (int i = 0; i < count; i++) {
-            result[i] = m.keyAt(i);
-        }
-        return result;
-    }
-
-    /**
-     * Set a transition from a specific scene to a named scene.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromScene Scene to transition from
-     * @param toName Named scene to transition to
-     * @param transition Transition to use
-     *
-     * @see #getTargetSceneNames(Scene)
-     */
-    public void setTransition(Scene fromScene, String toName, Transition transition) {
-        ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
-        if (m == null) {
-            m = new ArrayMap<String, Transition>();
-            mSceneNameTransitions.put(fromScene, m);
-        }
-        m.put(toName, transition);
-    }
-
-    /**
-     * Set a transition from a named scene to a concrete scene.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromName Named scene to transition from
-     * @param toScene Scene to transition to
-     * @param transition Transition to use
-     *
-     * @see #getNamedTransition(String, Scene)
-     */
-    public void setTransition(String fromName, Scene toScene, Transition transition) {
-        ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
-        if (m == null) {
-            m = new ArrayMap<Scene, Transition>();
-            mNameSceneTransitions.put(fromName, m);
-        }
-        m.put(toScene, transition);
+    public Transition getExitTransition(Scene fromScene) {
+        return mExitSceneTransitions.get(fromScene);
     }
 
     /**
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 5a8d2c8..e693b9e 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -167,6 +167,13 @@
     public static final int FX_SURFACE_DIM = 0x00020000;
 
     /**
+     * Surface creation flag: Creates a video plane Surface.
+     * This surface is backed by a hardware video plane. It is an error to lock
+     * a video plane surface, since it doesn't have a backing store.
+     */
+    public static final int FX_SURFACE_VIDEO_PLANE = 0x00040000;
+
+    /**
      * Mask used for FX values above.
      *
      */
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 65d3f6d..9b23b35 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -421,7 +421,10 @@
         mWindowType = type;
     }
 
-    private void updateWindow(boolean force, boolean redrawNeeded) {
+    /**
+     * @hide
+     */
+    protected void updateWindow(boolean force, boolean redrawNeeded) {
         if (!mHaveFrame) {
             return;
         }
diff --git a/core/java/android/view/VideoPlaneView.java b/core/java/android/view/VideoPlaneView.java
new file mode 100644
index 0000000..81dcf9d
--- /dev/null
+++ b/core/java/android/view/VideoPlaneView.java
@@ -0,0 +1,53 @@
+/*
+ * 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.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * Provides a dedicated surface embedded inside of a view hierarchy much like a
+ * {@link SurfaceView}, but the surface is actually backed by a hardware video
+ * plane.
+ *
+ * TODO: Eventually this should be separate from SurfaceView.
+ *
+ * @hide
+ */
+public class VideoPlaneView extends SurfaceView {
+    public VideoPlaneView(Context context) {
+        super(context);
+    }
+
+    public VideoPlaneView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public VideoPlaneView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public VideoPlaneView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void updateWindow(boolean force, boolean redrawNeeded) {
+        mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_VIDEO_PLANE;
+        super.updateWindow(force, redrawNeeded);
+    }
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f3bd9e6..de304da 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -101,7 +101,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -13617,11 +13619,7 @@
         }
 
         if (layerType == mLayerType) {
-            if (layerType != LAYER_TYPE_NONE && paint != mLayerPaint) {
-                mLayerPaint = paint == null ? new Paint() : paint;
-                invalidateParentCaches();
-                invalidate(true);
-            }
+            setLayerPaint(paint);
             return;
         }
 
@@ -18841,6 +18839,33 @@
         }
     }
 
+    /**
+     * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
+     * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
+     *                           a normal View or a ViewGroup with
+     *                           {@link android.view.ViewGroup#isTransitionGroup()} true.
+     * @hide
+     */
+    public void captureTransitioningViews(List<View> transitioningViews) {
+        if (getVisibility() == View.VISIBLE) {
+            transitioningViews.add(this);
+        }
+    }
+
+    /**
+     * Adds all Views that have {@link #getSharedElementName()} non-null to sharedElements.
+     * @param sharedElements Will contain all Views in the hierarchy having a shared element name.
+     * @hide
+     */
+    public void findSharedElements(Map<String, View> sharedElements) {
+        if (getVisibility() == VISIBLE) {
+            String sharedElementName = getSharedElementName();
+            if (sharedElementName != null) {
+                sharedElements.put(sharedElementName, this);
+            }
+        }
+    }
+
     //
     // Properties
     //
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9cd3c9d..cf5e8cf 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -31,6 +31,7 @@
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -50,6 +51,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 
@@ -2300,14 +2303,13 @@
      * individually during the transition.
      * @return True if the ViewGroup should be acted on together during an Activity transition.
      * The default value is false when the background is null and true when the background
-     * is not null.
-     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
+     * is not null or if {@link #getSharedElementName()} is not null.
      */
     public boolean isTransitionGroup() {
         if ((mGroupFlags & FLAG_IS_TRANSITION_GROUP_SET) != 0) {
             return ((mGroupFlags & FLAG_IS_TRANSITION_GROUP) != 0);
         } else {
-            return getBackground() != null;
+            return getBackground() != null || getSharedElementName() != null;
         }
     }
 
@@ -2318,7 +2320,6 @@
      *                          in Activity transitions. If false, the ViewGroup won't transition,
      *                          only its children. If true, the entire ViewGroup will transition
      *                          together.
-     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
      */
     public void setTransitionGroup(boolean isTransitionGroup) {
         mGroupFlags |= FLAG_IS_TRANSITION_GROUP_SET;
@@ -5880,6 +5881,37 @@
     protected void onSetLayoutParams(View child, LayoutParams layoutParams) {
     }
 
+    /** @hide */
+    @Override
+    public void captureTransitioningViews(List<View> transitioningViews) {
+        if (getVisibility() != View.VISIBLE) {
+            return;
+        }
+        if (isTransitionGroup()) {
+            transitioningViews.add(this);
+        } else {
+            int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = getChildAt(i);
+                child.captureTransitioningViews(transitioningViews);
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void findSharedElements(Map<String, View> sharedElements) {
+        if (getVisibility() != VISIBLE) {
+            return;
+        }
+        super.findSharedElements(sharedElements);
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            child.findSharedElements(sharedElements);
+        }
+    }
+
     /**
      * LayoutParams are used by views to tell their parents how they want to be
      * laid out. See
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2b32d70..a338e6e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -267,6 +267,10 @@
     HardwareLayer mResizeBuffer;
     long mResizeBufferStartTime;
     int mResizeBufferDuration;
+    // Used to block the creation of the ResizeBuffer due to invalidations in
+    // the previous DisplayList tree that must prevent re-execution.
+    // Currently this means a functor was detached.
+    boolean mBlockResizeBuffer;
     static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
     private ArrayList<LayoutTransition> mPendingTransitions;
 
@@ -667,6 +671,7 @@
     }
 
     public void detachFunctor(int functor) {
+        mBlockResizeBuffer = true;
         if (mAttachInfo.mHardwareRenderer != null) {
             mAttachInfo.mHardwareRenderer.detachFunctor(functor);
         }
@@ -1454,7 +1459,8 @@
                             !mAttachInfo.mTurnOffWindowResizeAnim &&
                             mAttachInfo.mHardwareRenderer != null &&
                             mAttachInfo.mHardwareRenderer.isEnabled() &&
-                            lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
+                            lp != null && !PixelFormat.formatHasAlpha(lp.format)
+                            && !mBlockResizeBuffer) {
 
                         disposeResizeBuffer();
 
@@ -2377,6 +2383,7 @@
                 mCurrentDirty.set(dirty);
                 dirty.setEmpty();
 
+                mBlockResizeBuffer = false;
                 attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
                         animating ? null : mCurrentDirty);
             } else {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 11740ab..24b8248 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -29,9 +29,12 @@
 import android.os.IBinder;
 import android.os.SystemProperties;
 import android.transition.Scene;
+import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.view.accessibility.AccessibilityEvent;
 
+import java.util.Map;
+
 /**
  * Abstract base class for a top-level window look and behavior policy.  An
  * instance of this class should be used as the top-level view added to the
@@ -1386,30 +1389,43 @@
      * @hide
      */
     public interface SceneTransitionListener {
-        void enterSharedElement(Bundle transitionArgs);
         void nullPendingTransition();
         void convertFromTranslucent();
         void convertToTranslucent();
+        void sharedElementStart(Transition transition);
+        void sharedElementEnd();
     }
 
     /**
-     * Controls how the background fade is triggered. If fadeEarly is true, the Window background
-     * will fade in as soon as the shared elements are ready to switch. If fadeEarly is false,
-     * the background will fade only after the calling Activity's exit transition completes.
-     * By default, the Window will fade in when the calling Activity's exit transition completes.
+     * Controls when the Activity enter scene is triggered and the background is faded in. If
+     * triggerEarly is true, the enter scene will begin as soon as possible and the background
+     * will fade in when all shared elements are ready to begin transitioning. If triggerEarly is
+     * false, the Activity enter scene and background fade will be triggered when the calling
+     * Activity's exit transition completes.
      *
-     * @param fadeEarly Set to true to fade out the exiting Activity as soon as the shared elements
-     *                  are transferred. Set to false to fade out the exiting Activity as soon as
-     *                  the shared element is transferred.
-     * @hide
+     * @param triggerEarly Set to true to have the Activity enter scene transition in as early as
+     *                     possible or set to false to wait for the calling Activity to exit first.
      */
-    public void setEarlyBackgroundTransition(boolean fadeEarly) {
+    public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
     }
 
     /**
      * Start the exit transition.
      * @hide
      */
-    public void startExitTransition(ActivityOptions activityOptions) {
+    public Bundle startExitTransition(ActivityOptions options) {
+        return null;
+    }
+
+    /**
+     * On entering Activity Scene transitions, shared element names may be mapped from a
+     * source Activity's specified name to a unique shared element name in the View hierarchy.
+     * Under most circumstances, mapping is not necessary - a single View will have the
+     * shared element name given by the calling Activity. However, if there are several similar
+     * Views (e.g. in a ListView), the correct shared element must be mapped.
+     * @param sharedElementNames A mapping from the calling Activity's assigned shared element
+     *                           name to a unique shared element name in the View hierarchy.
+     */
+    public void mapTransitionTargets(Map<String, String> sharedElementNames) {
     }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 53a4c0d0..55956bf 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -98,7 +98,7 @@
      * the given view hierarchy's {@link View#onDetachedFromWindow()
      * View.onDetachedFromWindow()} methods before returning.  This is not
      * for normal applications; using it correctly requires great care.
-     * 
+     *
      * @param view The view to be removed.
      */
     public void removeViewImmediate(View view);
@@ -112,7 +112,7 @@
          */
         @ViewDebug.ExportedProperty
         public int x;
-        
+
         /**
          * Y position for this window.  With the default gravity it is ignored.
          * When using {@link Gravity#TOP} or {@link Gravity#BOTTOM} it provides
@@ -161,7 +161,7 @@
          * be used by applications, and a special permission is required
          * to use them.
          * </ul>
-         * 
+         *
          * @see #TYPE_BASE_APPLICATION
          * @see #TYPE_APPLICATION
          * @see #TYPE_APPLICATION_STARTING
@@ -223,12 +223,12 @@
             @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION")
         })
         public int type;
-    
+
         /**
          * Start of window types that represent normal application windows.
          */
         public static final int FIRST_APPLICATION_WINDOW = 1;
-        
+
         /**
          * Window type: an application window that serves as the "base" window
          * of the overall application; all other application windows will
@@ -236,14 +236,14 @@
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_BASE_APPLICATION   = 1;
-        
+
         /**
          * Window type: a normal application window.  The {@link #token} must be
          * an Activity token identifying who the window belongs to.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_APPLICATION        = 2;
-    
+
         /**
          * Window type: special application window that is displayed while the
          * application is starting.  Not for use by applications themselves;
@@ -252,12 +252,12 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_APPLICATION_STARTING = 3;
-    
+
         /**
          * End of types of application windows.
          */
         public static final int LAST_APPLICATION_WINDOW = 99;
-    
+
         /**
          * Start of types of sub-windows.  The {@link #token} of these windows
          * must be set to the window they are attached to.  These types of
@@ -265,19 +265,19 @@
          * coordinate space is relative to their attached window.
          */
         public static final int FIRST_SUB_WINDOW        = 1000;
-    
+
         /**
          * Window type: a panel on top of an application window.  These windows
          * appear on top of their attached window.
          */
         public static final int TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW;
-    
+
         /**
          * Window type: window for showing media (such as video).  These windows
          * are displayed behind their attached window.
          */
         public static final int TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1;
-    
+
         /**
          * Window type: a sub-panel on top of an application window.  These
          * windows are displayed on top their attached window and any
@@ -290,7 +290,7 @@
          * as a child of its container.
          */
         public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3;
-        
+
         /**
          * Window type: window for showing overlays on top of media windows.
          * These windows are displayed between TYPE_APPLICATION_MEDIA and the
@@ -299,18 +299,18 @@
          * @hide
          */
         public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4;
-    
+
         /**
          * End of types of sub-windows.
          */
         public static final int LAST_SUB_WINDOW         = 1999;
-        
+
         /**
          * Start of system-specific window types.  These are not normally
          * created by applications.
          */
         public static final int FIRST_SYSTEM_WINDOW     = 2000;
-    
+
         /**
          * Window type: the status bar.  There can be only one status bar
          * window; it is placed at the top of the screen, and all other
@@ -318,14 +318,14 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW;
-    
+
         /**
          * Window type: the search bar.  There can be only one search bar
          * window; it is placed at the top of the screen.
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1;
-    
+
         /**
          * Window type: phone.  These are non-application windows providing
          * user interaction with the phone (in particular incoming calls).
@@ -334,26 +334,26 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
-    
+
         /**
          * Window type: system window, such as low power alert. These windows
          * are always on top of application windows.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
-        
+
         /**
          * Window type: keyguard window.
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
-        
+
         /**
          * Window type: transient notifications.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
-        
+
         /**
          * Window type: system overlay windows, which need to be displayed
          * on top of everything else.  These windows must not take input
@@ -361,7 +361,7 @@
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
-        
+
         /**
          * Window type: priority phone UI, which needs to be displayed even if
          * the keyguard is active.  These windows must not take input
@@ -369,26 +369,26 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;
-        
+
         /**
          * Window type: panel that slides out from the status bar
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8;
-    
+
         /**
          * Window type: dialogs that the keyguard shows
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9;
-        
+
         /**
          * Window type: internal system error windows, appear on top of
          * everything they can.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;
-        
+
         /**
          * Window type: internal input methods windows, which appear above
          * the normal UI.  Application windows may be resized or panned to keep
@@ -559,16 +559,16 @@
         /** @deprecated this is ignored, this value is set automatically when needed. */
         @Deprecated
         public static final int MEMORY_TYPE_PUSH_BUFFERS = 3;
-        
+
         /**
          * @deprecated this is ignored
          */
         @Deprecated
         public int memoryType;
-        
+
         /** Window flag: as long as this window is visible to the user, allow
-         *  the lock screen to activate while the screen is on. 
-         *  This can be used independently, or in combination with 
+         *  the lock screen to activate while the screen is on.
+         *  This can be used independently, or in combination with
          *  {@link #FLAG_KEEP_SCREEN_ON} and/or {@link #FLAG_SHOW_WHEN_LOCKED} */
         public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001;
 
@@ -586,47 +586,47 @@
          * instead go to whatever focusable window is behind it.  This flag
          * will also enable {@link #FLAG_NOT_TOUCH_MODAL} whether or not that
          * is explicitly set.
-         * 
+         *
          * <p>Setting this flag also implies that the window will not need to
          * interact with
-         * a soft input method, so it will be Z-ordered and positioned 
+         * a soft input method, so it will be Z-ordered and positioned
          * independently of any active input method (typically this means it
          * gets Z-ordered on top of the input method, so it can use the full
          * screen for its content and cover the input method if needed.  You
          * can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */
         public static final int FLAG_NOT_FOCUSABLE      = 0x00000008;
-        
+
         /** Window flag: this window can never receive touch events. */
         public static final int FLAG_NOT_TOUCHABLE      = 0x00000010;
-        
+
         /** Window flag: even when this window is focusable (its
          * {@link #FLAG_NOT_FOCUSABLE} is not set), allow any pointer events
          * outside of the window to be sent to the windows behind it.  Otherwise
          * it will consume all pointer events itself, regardless of whether they
          * are inside of the window. */
         public static final int FLAG_NOT_TOUCH_MODAL    = 0x00000020;
-        
+
         /** Window flag: when set, if the device is asleep when the touch
          * screen is pressed, you will receive this first touch event.  Usually
          * the first touch event is consumed by the system since the user can
          * not see what they are pressing on.
          */
         public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;
-        
+
         /** Window flag: as long as this window is visible to the user, keep
          *  the device's screen turned on and bright. */
         public static final int FLAG_KEEP_SCREEN_ON     = 0x00000080;
-        
+
         /** Window flag: place the window within the entire screen, ignoring
          *  decorations around the border (such as the status bar).  The
          *  window must correctly position its contents to take the screen
          *  decoration into account.  This flag is normally set for you
          *  by Window as described in {@link Window#setFlags}. */
         public static final int FLAG_LAYOUT_IN_SCREEN   = 0x00000100;
-        
+
         /** Window flag: allow window to extend outside of the screen. */
         public static final int FLAG_LAYOUT_NO_LIMITS   = 0x00000200;
-        
+
         /**
          * Window flag: hide all screen decorations (such as the status bar) while
          * this window is displayed.  This allows the window to use the entire
@@ -648,17 +648,17 @@
          * {@link android.R.style#Theme_DeviceDefault_Light_NoActionBar_Fullscreen}.</p>
          */
         public static final int FLAG_FULLSCREEN      = 0x00000400;
-        
+
         /** Window flag: override {@link #FLAG_FULLSCREEN} and force the
          *  screen decorations (such as the status bar) to be shown. */
         public static final int FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800;
-        
+
         /** Window flag: turn on dithering when compositing this window to
          *  the screen.
          * @deprecated This flag is no longer used. */
         @Deprecated
         public static final int FLAG_DITHER             = 0x00001000;
-        
+
         /** Window flag: treat the content of the window as secure, preventing
          * it from appearing in screenshots or from being viewed on non-secure
          * displays.
@@ -667,21 +667,21 @@
          * secure surfaces and secure displays.
          */
         public static final int FLAG_SECURE             = 0x00002000;
-        
+
         /** Window flag: a special mode where the layout parameters are used
          * to perform scaling of the surface when it is composited to the
          * screen. */
         public static final int FLAG_SCALED             = 0x00004000;
-        
+
         /** Window flag: intended for windows that will often be used when the user is
          * holding the screen against their face, it will aggressively filter the event
          * stream to prevent unintended presses in this situation that may not be
-         * desired for a particular window, when such an event stream is detected, the 
+         * desired for a particular window, when such an event stream is detected, the
          * application will receive a CANCEL motion event to indicate this so applications
-         * can handle this accordingly by taking no action on the event 
+         * can handle this accordingly by taking no action on the event
          * until the finger is released. */
         public static final int FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000;
-        
+
         /** Window flag: a special option only for use in combination with
          * {@link #FLAG_LAYOUT_IN_SCREEN}.  When requesting layout in the
          * screen your window may appear on top of or behind screen decorations
@@ -690,7 +690,7 @@
          * content is not covered by screen decorations.  This flag is normally
          * set for you by Window as described in {@link Window#setFlags}.*/
         public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
-        
+
         /** Window flag: invert the state of {@link #FLAG_NOT_FOCUSABLE} with
          * respect to how this window interacts with the current method.  That
          * is, if FLAG_NOT_FOCUSABLE is set and this flag is set, then the
@@ -701,7 +701,7 @@
          * to use more space and cover the input method.
          */
         public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
-        
+
         /** Window flag: if you have set {@link #FLAG_NOT_TOUCH_MODAL}, you
          * can set this flag to receive a single special MotionEvent with
          * the action
@@ -711,7 +711,7 @@
          * first down as an ACTION_OUTSIDE.
          */
         public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
-        
+
         /** Window flag: special flag to let windows be shown when the screen
          * is locked. This will let application windows take precedence over
          * key guard or any other lock screens. Can be used with
@@ -741,13 +741,13 @@
          * {@link android.R.style#Theme_DeviceDefault_Wallpaper_NoTitleBar}.</p>
          */
         public static final int FLAG_SHOW_WALLPAPER = 0x00100000;
-        
+
         /** Window flag: when set as a window is being added or made
          * visible, once the window has been shown then the system will
          * poke the power manager's user activity (as if the user had woken
          * up the device) to turn the screen on. */
         public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
-        
+
         /** Window flag: when set the window will cause the keyguard to
          * be dismissed, only if it is not a secure lock keyguard.  Because such
          * a keyguard is not needed for security, it will never re-appear if
@@ -761,7 +761,7 @@
          * also been set.
          */
         public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
-        
+
         /** Window flag: when set the window will accept for touch events
          * outside of its bounds to be sent to other windows that also
          * support split touch.  When this flag is not set, the first pointer
@@ -773,7 +773,7 @@
          * to be split across multiple windows.
          */
         public static final int FLAG_SPLIT_TOUCH = 0x00800000;
-        
+
         /**
          * <p>Indicates whether this window should be hardware accelerated.
          * Requesting hardware acceleration does not guarantee it will happen.</p>
@@ -916,7 +916,7 @@
 
         /**
          * Various behavioral options/flags.  Default is none.
-         * 
+         *
          * @see #FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
          * @see #FLAG_DIM_BEHIND
          * @see #FLAG_NOT_FOCUSABLE
@@ -1014,10 +1014,10 @@
          * as if it was.
          * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
          * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
-         * is generally disabled. This flag must be specified in addition to 
+         * is generally disabled. This flag must be specified in addition to
          * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
          * windows.
-         * 
+         *
          * @hide
          */
         public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
@@ -1028,7 +1028,7 @@
          * If certain parts of the UI that really do want to use hardware
          * acceleration, this flag can be set to force it.  This is basically
          * for the lock screen.  Anyone else using it, you are probably wrong.
-         * 
+         *
          * @hide
          */
         public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
@@ -1086,6 +1086,11 @@
          * {@hide} */
         public static final int PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR = 0x00000200;
 
+        /** Window flag: the window is backed by a video plane, instead of a
+         * regular surface.
+         * {@hide} */
+        public static final int PRIVATE_FLAG_VIDEO_PLANE = 0x00000400;
+
         /**
          * Control flags that are private to the platform.
          * @hide
@@ -1100,9 +1105,9 @@
          * flags and returns true if the combination of the two corresponds
          * to a window that needs to be behind the input method so that the
          * user can type into it.
-         * 
+         *
          * @param flags The current window manager flags.
-         * 
+         *
          * @return Returns true if such a window should be behind/interact
          * with an input method, false if not.
          */
@@ -1114,63 +1119,63 @@
             }
             return false;
         }
-        
+
         /**
          * Mask for {@link #softInputMode} of the bits that determine the
          * desired visibility state of the soft input area for this window.
          */
         public static final int SOFT_INPUT_MASK_STATE = 0x0f;
-        
+
         /**
          * Visibility state for {@link #softInputMode}: no state has been specified.
          */
         public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
-        
+
         /**
          * Visibility state for {@link #softInputMode}: please don't change the state of
          * the soft input area.
          */
         public static final int SOFT_INPUT_STATE_UNCHANGED = 1;
-        
+
         /**
          * Visibility state for {@link #softInputMode}: please hide any soft input
          * area when normally appropriate (when the user is navigating
          * forward to your window).
          */
         public static final int SOFT_INPUT_STATE_HIDDEN = 2;
-        
+
         /**
          * Visibility state for {@link #softInputMode}: please always hide any
          * soft input area when this window receives focus.
          */
         public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
-        
+
         /**
          * Visibility state for {@link #softInputMode}: please show the soft
          * input area when normally appropriate (when the user is navigating
          * forward to your window).
          */
         public static final int SOFT_INPUT_STATE_VISIBLE = 4;
-        
+
         /**
          * Visibility state for {@link #softInputMode}: please always make the
          * soft input area visible when this window receives input focus.
          */
         public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;
-        
+
         /**
          * Mask for {@link #softInputMode} of the bits that determine the
          * way that the window should be adjusted to accommodate the soft
          * input window.
          */
         public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;
-        
+
         /** Adjustment option for {@link #softInputMode}: nothing specified.
          * The system will try to pick one or
          * the other depending on the contents of the window.
          */
         public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;
-        
+
         /** Adjustment option for {@link #softInputMode}: set to allow the
          * window to be resized when an input
          * method is shown, so that its contents are not covered by the input
@@ -1183,7 +1188,7 @@
          * not resize, but will stay fullscreen.
          */
         public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;
-        
+
         /** Adjustment option for {@link #softInputMode}: set to have a window
          * pan when an input method is
          * shown, so it doesn't need to deal with resizing but just panned
@@ -1193,7 +1198,7 @@
          * the other depending on the contents of the window.
          */
         public static final int SOFT_INPUT_ADJUST_PAN = 0x20;
-        
+
         /** Adjustment option for {@link #softInputMode}: set to have a window
          * not adjust for a shown input method.  The window will not be resized,
          * and it will not be panned to make its focus visible.
@@ -1212,7 +1217,7 @@
         /**
          * Desired operating mode for any soft input area.  May be any combination
          * of:
-         * 
+         *
          * <ul>
          * <li> One of the visibility states
          * {@link #SOFT_INPUT_STATE_UNSPECIFIED}, {@link #SOFT_INPUT_STATE_UNCHANGED},
@@ -1229,7 +1234,7 @@
          * {@link android.R.attr#windowSoftInputMode} attribute.</p>
          */
         public int softInputMode;
-        
+
         /**
          * Placement of window within the screen as per {@link Gravity}.  Both
          * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int,
@@ -1246,7 +1251,7 @@
          * @see Gravity
          */
         public int gravity;
-    
+
         /**
          * The horizontal margin, as a percentage of the container's width,
          * between the container and the widget.  See
@@ -1255,7 +1260,7 @@
          * field is added with {@link #x} to supply the <var>xAdj</var> parameter.
          */
         public float horizontalMargin;
-    
+
         /**
          * The vertical margin, as a percentage of the container's height,
          * between the container and the widget.  See
@@ -1264,26 +1269,26 @@
          * field is added with {@link #y} to supply the <var>yAdj</var> parameter.
          */
         public float verticalMargin;
-    
+
         /**
          * The desired bitmap format.  May be one of the constants in
          * {@link android.graphics.PixelFormat}.  Default is OPAQUE.
          */
         public int format;
-    
+
         /**
          * A style resource defining the animations to use for this window.
          * This must be a system resource; it can not be an application resource
          * because the window manager does not have access to applications.
          */
         public int windowAnimations;
-    
+
         /**
          * An alpha value to apply to this entire window.
          * An alpha of 1.0 means fully opaque and 0.0 means fully transparent
          */
         public float alpha = 1.0f;
-    
+
         /**
          * When {@link #FLAG_DIM_BEHIND} is set, this is the amount of dimming
          * to apply.  Range is from 1.0 for completely opaque to 0.0 for no
@@ -1311,7 +1316,7 @@
          * to the hightest value when this window is in front.
          */
         public static final float BRIGHTNESS_OVERRIDE_FULL = 1.0f;
-    
+
         /**
          * This can be used to override the user's preferred brightness of
          * the screen.  A value of less than 0, the default, means to use the
@@ -1319,7 +1324,7 @@
          * dark to full bright.
          */
         public float screenBrightness = BRIGHTNESS_OVERRIDE_NONE;
-        
+
         /**
          * This can be used to override the standard behavior of the button and
          * keyboard backlights.  A value of less than 0, the default, means to
@@ -1353,7 +1358,7 @@
          * opaque windows have the #FLAG_FULLSCREEN bit set and are not covered
          * by other windows. All other situations default to the
          * {@link #ROTATION_ANIMATION_ROTATE} behavior.
-         * 
+         *
          * @see #ROTATION_ANIMATION_ROTATE
          * @see #ROTATION_ANIMATION_CROSSFADE
          * @see #ROTATION_ANIMATION_JUMPCUT
@@ -1365,18 +1370,18 @@
          * you.
          */
         public IBinder token = null;
-    
+
         /**
          * Name of the package owning this window.
          */
         public String packageName = null;
-        
+
         /**
          * Specific orientation value for a window.
          * May be any of the same values allowed
-         * for {@link android.content.pm.ActivityInfo#screenOrientation}. 
-         * If not set, a default value of 
-         * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} 
+         * for {@link android.content.pm.ActivityInfo#screenOrientation}.
+         * If not set, a default value of
+         * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
          * will be used.
          */
         public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1398,7 +1403,7 @@
 
         /**
          * Get callbacks about the system ui visibility changing.
-         * 
+         *
          * TODO: Maybe there should be a bitfield of optional callbacks that we need.
          *
          * @hide
@@ -1464,34 +1469,34 @@
             type = TYPE_APPLICATION;
             format = PixelFormat.OPAQUE;
         }
-        
+
         public LayoutParams(int _type) {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = _type;
             format = PixelFormat.OPAQUE;
         }
-    
+
         public LayoutParams(int _type, int _flags) {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = _type;
             flags = _flags;
             format = PixelFormat.OPAQUE;
         }
-    
+
         public LayoutParams(int _type, int _flags, int _format) {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = _type;
             flags = _flags;
             format = _format;
         }
-        
+
         public LayoutParams(int w, int h, int _type, int _flags, int _format) {
             super(w, h);
             type = _type;
             flags = _flags;
             format = _format;
         }
-        
+
         public LayoutParams(int w, int h, int xpos, int ypos, int _type,
                 int _flags, int _format) {
             super(w, h);
@@ -1501,18 +1506,18 @@
             flags = _flags;
             format = _format;
         }
-    
+
         public final void setTitle(CharSequence title) {
             if (null == title)
                 title = "";
-    
+
             mTitle = TextUtils.stringOrSpannedString(title);
         }
-    
+
         public final CharSequence getTitle() {
             return mTitle;
         }
-    
+
         public int describeContents() {
             return 0;
         }
@@ -1546,19 +1551,19 @@
             out.writeInt(inputFeatures);
             out.writeLong(userActivityTimeout);
         }
-        
+
         public static final Parcelable.Creator<LayoutParams> CREATOR
                     = new Parcelable.Creator<LayoutParams>() {
             public LayoutParams createFromParcel(Parcel in) {
                 return new LayoutParams(in);
             }
-    
+
             public LayoutParams[] newArray(int size) {
                 return new LayoutParams[size];
             }
         };
-    
-    
+
+
         public LayoutParams(Parcel in) {
             width = in.readInt();
             height = in.readInt();
@@ -1588,7 +1593,7 @@
             inputFeatures = in.readInt();
             userActivityTimeout = in.readLong();
         }
-    
+
         @SuppressWarnings({"PointlessBitwiseExpression"})
         public static final int LAYOUT_CHANGED = 1<<0;
         public static final int TYPE_CHANGED = 1<<1;
@@ -1622,10 +1627,10 @@
 
         // internal buffer to backup/restore parameters under compatibility mode.
         private int[] mCompatibilityParamsBackup = null;
-        
+
         public final int copyFrom(LayoutParams o) {
             int changes = 0;
-    
+
             if (width != o.width) {
                 width = o.width;
                 changes |= LAYOUT_CHANGED;
@@ -1724,7 +1729,7 @@
                 rotationAnimation = o.rotationAnimation;
                 changes |= ROTATION_ANIMATION_CHANGED;
             }
-    
+
             if (screenOrientation != o.screenOrientation) {
                 screenOrientation = o.screenOrientation;
                 changes |= SCREEN_ORIENTATION_CHANGED;
@@ -1754,7 +1759,7 @@
 
             return changes;
         }
-    
+
         @Override
         public String debug(String output) {
             output += "Contents of " + this + ":";
@@ -1765,7 +1770,7 @@
             Log.d("Debug", "WindowManager.LayoutParams={title=" + mTitle + "}");
             return "";
         }
-    
+
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder(256);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 86fdae3..47d42dc 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -56,7 +56,6 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.ViewRootImpl;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -2313,6 +2312,7 @@
 
                 // If we failed to re-bind the data, scrap the obtained view.
                 if (updatedView != transientView) {
+                    setItemViewLayoutParams(updatedView, position);
                     mRecycler.addScrapView(updatedView, position);
                 }
             }
@@ -2343,19 +2343,7 @@
             child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
 
-        if (mAdapterHasStableIds) {
-            final ViewGroup.LayoutParams vlp = child.getLayoutParams();
-            LayoutParams lp;
-            if (vlp == null) {
-                lp = (LayoutParams) generateDefaultLayoutParams();
-            } else if (!checkLayoutParams(vlp)) {
-                lp = (LayoutParams) generateLayoutParams(vlp);
-            } else {
-                lp = (LayoutParams) vlp;
-            }
-            lp.itemId = mAdapter.getItemId(position);
-            child.setLayoutParams(lp);
-        }
+        setItemViewLayoutParams(child, position);
 
         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
             if (mAccessibilityDelegate == null) {
@@ -2371,6 +2359,24 @@
         return child;
     }
 
+    private void setItemViewLayoutParams(View child, int position) {
+        final ViewGroup.LayoutParams vlp = child.getLayoutParams();
+        LayoutParams lp;
+        if (vlp == null) {
+            lp = (LayoutParams) generateDefaultLayoutParams();
+        } else if (!checkLayoutParams(vlp)) {
+            lp = (LayoutParams) generateLayoutParams(vlp);
+        } else {
+            lp = (LayoutParams) vlp;
+        }
+
+        if (mAdapterHasStableIds) {
+            lp.itemId = mAdapter.getItemId(position);
+        }
+        lp.viewType = mAdapter.getItemViewType(position);
+        child.setLayoutParams(lp);
+    }
+
     class ListItemAccessibilityDelegate extends AccessibilityDelegate {
         @Override
         public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
@@ -4472,6 +4478,7 @@
      * scroll such that the indicated position is displayed, but it will
      * stop early if scrolling further would scroll boundPosition out of
      * view.
+     *
      * @param position Scroll to this adapter position.
      * @param boundPosition Do not scroll if it would move this adapter
      *          position out of view.
@@ -7121,7 +7128,10 @@
      * understanding of layout.
      */
     abstract class AbsSubPositionScroller extends AbsPositionScroller {
-        private static final int DEFAULT_SCROLL_DURATION = 200;
+        private static final int DURATION_AUTO = -1;
+
+        private static final int DURATION_AUTO_MIN = 100;
+        private static final int DURATION_AUTO_MAX = 500;
 
         private final SubScroller mSubScroller = new SubScroller();
 
@@ -7150,9 +7160,17 @@
                 return;
             }
 
+            if (mAdapter == null) {
+                // Can't scroll anywhere without an adapter.
+                return;
+            }
+
+            final int itemCount = getCount();
+            final int clampedPosition = MathUtils.constrain(targetPosition, 0, itemCount - 1);
+            final int clampedBoundPosition = MathUtils.constrain(boundPosition, 0, itemCount - 1);
             final int firstPosition = getFirstVisiblePosition();
             final int lastPosition = firstPosition + getChildCount();
-            final int targetRow = getRowForPosition(targetPosition);
+            final int targetRow = getRowForPosition(clampedPosition);
             final int firstRow = getRowForPosition(firstPosition);
             final int lastRow = getRowForPosition(lastPosition);
             if (useOffset || targetRow <= firstRow) {
@@ -7161,15 +7179,15 @@
             } else if (targetRow >= lastRow - 1) {
                 // Offset so the target row is bottom-aligned.
                 final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
-                mOffset = listHeight - getHeightForPosition(targetPosition);
+                mOffset = getHeightForPosition(clampedPosition) - listHeight;
             } else {
                 // Don't scroll, target is entirely on-screen.
                 return;
             }
 
             float endSubRow = targetRow;
-            if (boundPosition != INVALID_POSITION) {
-                final int boundRow = getRowForPosition(boundPosition);
+            if (clampedBoundPosition != INVALID_POSITION) {
+                final int boundRow = getRowForPosition(clampedBoundPosition);
                 if (boundRow >= firstRow && boundRow < lastRow && boundRow != targetRow) {
                     endSubRow = computeBoundSubRow(targetRow, boundRow);
                 }
@@ -7183,51 +7201,75 @@
             final int firstChildHeight = firstChild.getHeight();
             final float startOffsetRatio;
             if (firstChildHeight == 0) {
-                startOffsetRatio = 1;
+                startOffsetRatio = 0;
             } else {
                 startOffsetRatio = -firstChild.getTop() / (float) firstChildHeight;
             }
 
-            final float startSubRow = firstRow + startOffsetRatio;
+            final float startSubRow = MathUtils.constrain(
+                    firstRow + startOffsetRatio, 0, getCount());
             if (startSubRow == endSubRow && mOffset == 0) {
                 // Don't scroll, target is already in position.
                 return;
             }
 
-            mSubScroller.startScroll(startSubRow, endSubRow, duration);
+            final int durationMillis;
+            if (duration == DURATION_AUTO) {
+                final float subRowDelta = Math.abs(startSubRow - endSubRow);
+                durationMillis = (int) MathUtils.lerp(
+                        DURATION_AUTO_MIN, DURATION_AUTO_MAX, subRowDelta / getCount());
+            } else {
+                durationMillis = duration;
+            }
+
+            mSubScroller.startScroll(startSubRow, endSubRow, durationMillis);
 
             postOnAnimation(mAnimationFrame);
         }
 
-        private float computeBoundSubRow(int targetRow, int boundRow) {
-            // If the final offset is greater than 0, we're aiming above the
-            // suggested target row. Compute the actual target row and offset
-            // within that row by subtracting the height of each preceeding row.
-            int remainingOffset = mOffset;
+        /**
+         * Given a target row and offset, computes the sub-row position that
+         * aligns with the top of the list. If the offset is negative, the
+         * resulting sub-row will be smaller than the target row.
+         */
+        private float resolveOffset(int targetRow, int offset) {
+            // Compute the target sub-row position by finding the actual row
+            // indicated by the target and offset.
+            int remainingOffset = offset;
             int targetHeight = getHeightForRow(targetRow);
-            while (targetRow > 1 && remainingOffset > targetHeight) {
-                targetRow--;
-                remainingOffset -= targetHeight;
-                targetHeight = getHeightForRow(targetRow);
+            if (offset < 0) {
+                // Subtract row heights until we find the right row.
+                while (targetRow > 0 && remainingOffset < 0) {
+                    remainingOffset += targetHeight;
+                    targetRow--;
+                    targetHeight = getHeightForRow(targetRow);
+                }
+            } else if (offset > 0) {
+                // Add row heights until we find the right row.
+                while (targetRow < getCount() - 1 && remainingOffset > targetHeight) {
+                    remainingOffset -= targetHeight;
+                    targetRow++;
+                    targetHeight = getHeightForRow(targetRow);
+                }
             }
 
-            // Compute the offset within the actual target row.
             final float targetOffsetRatio;
-            if (remainingOffset > 0) {
-                // We can't reach that offset given the row count.
+            if (remainingOffset < 0 || targetHeight == 0) {
                 targetOffsetRatio = 0;
-            } else if (targetHeight == 0) {
-                targetOffsetRatio = 1;
             } else {
                 targetOffsetRatio = remainingOffset / (float) targetHeight;
             }
 
-            // The final offset has been accounted for, reset it.
-            final float targetSubRow = targetRow - targetOffsetRatio;
+            return targetRow + targetOffsetRatio;
+        }
+
+        private float computeBoundSubRow(int targetRow, int boundRow) {
+            final float targetSubRow = resolveOffset(targetRow, mOffset);
             mOffset = 0;
 
+            // The target row is below the bound row, so the end position would
+            // push the bound position above the list. Abort!
             if (targetSubRow >= boundRow) {
-                // End position would push the bound position above the list.
                 return boundRow;
             }
 
@@ -7235,39 +7277,24 @@
             // bound position's view further below the list.
             final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
             final int boundHeight = getHeightForRow(boundRow);
-            int endRow = boundRow;
-            int totalHeight = boundHeight;
-            int endHeight;
-            do {
-                endRow--;
-                endHeight = getHeightForRow(endRow);
-                totalHeight += endHeight;
-            } while (totalHeight < listHeight && endRow > 0);
+            final float boundSubRow = resolveOffset(boundRow, -listHeight + boundHeight);
 
-            final float endOffsetRatio;
-            if (endHeight == 0) {
-                endOffsetRatio = 1;
-            } else {
-                endOffsetRatio = (totalHeight - listHeight) / (float) endHeight;
-            }
-
-            final float boundSubRow = endRow + endOffsetRatio;
             return Math.max(boundSubRow, targetSubRow);
         }
 
         @Override
         public void start(int position) {
-            scrollToPosition(position, false, 0, INVALID_POSITION, DEFAULT_SCROLL_DURATION);
+            scrollToPosition(position, false, 0, INVALID_POSITION, DURATION_AUTO);
         }
 
         @Override
         public void start(int position, int boundPosition) {
-            scrollToPosition(position, false, 0, boundPosition, DEFAULT_SCROLL_DURATION);
+            scrollToPosition(position, false, 0, boundPosition, DURATION_AUTO);
         }
 
         @Override
         public void startWithOffset(int position, int offset) {
-            scrollToPosition(position, true, offset, INVALID_POSITION, DEFAULT_SCROLL_DURATION);
+            scrollToPosition(position, true, offset, INVALID_POSITION, DURATION_AUTO);
         }
 
         @Override
@@ -7319,7 +7346,7 @@
             final int rowHeight = getHeightForRow(row);
             final int offset = (int) (rowHeight * (subRow - row));
             final int addOffset = (int) (mOffset * mSubScroller.getInterpolatedValue());
-            setSelectionFromTop(position, -offset + addOffset);
+            setSelectionFromTop(position, -offset - addOffset);
 
             if (shouldPost) {
                 postOnAnimation(mAnimationFrame);
@@ -7338,7 +7365,7 @@
      * Scroller capable of returning floating point positions.
      */
     static class SubScroller {
-        private final Interpolator mInterpolator;
+        private static final Interpolator INTERPOLATOR = new AccelerateDecelerateInterpolator();
 
         private float mStartPosition;
         private float mEndPosition;
@@ -7348,18 +7375,6 @@
         private float mPosition;
         private float mInterpolatedValue;
 
-        public SubScroller() {
-            this(null);
-        }
-
-        public SubScroller(Interpolator interpolator) {
-            if (interpolator == null) {
-                mInterpolator = new AccelerateDecelerateInterpolator();
-            } else {
-                mInterpolator = interpolator;
-            }
-        }
-
         public void startScroll(float startPosition, float endPosition, int duration) {
             mStartPosition = startPosition;
             mEndPosition = endPosition;
@@ -7379,7 +7394,7 @@
                 value = MathUtils.constrain(elapsed / (float) mDuration, 0, 1);
             }
 
-            mInterpolatedValue = mInterpolator.getInterpolation(value);
+            mInterpolatedValue = INTERPOLATOR.getInterpolation(value);
             mPosition = (mEndPosition - mStartPosition) * mInterpolatedValue + mStartPosition;
 
             return elapsed < mDuration;
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 65f1ab7..82e624d 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -667,6 +667,7 @@
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
         boolean matchWidth = false;
+        boolean skippedMeasure = false;
 
         final int baselineChildIndex = mBaselineAlignedChildIndex;        
         final boolean useLargestChild = mUseLargestChild;
@@ -701,6 +702,7 @@
                 // there is any leftover space.
                 final int totalLength = mTotalLength;
                 mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
+                skippedMeasure = true;
             } else {
                 int oldHeight = Integer.MIN_VALUE;
 
@@ -827,9 +829,10 @@
         heightSize = heightSizeAndState & MEASURED_SIZE_MASK;
         
         // Either expand children with weight to take up available space or
-        // shrink them if they extend beyond our current bounds
+        // shrink them if they extend beyond our current bounds. If we skipped
+        // measurement on any children, we need to measure them now.
         int delta = heightSize - mTotalLength;
-        if (delta != 0 && totalWeight > 0.0f) {
+        if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
             mTotalLength = 0;
@@ -995,6 +998,7 @@
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
         boolean matchHeight = false;
+        boolean skippedMeasure = false;
 
         if (mMaxAscent == null || mMaxDescent == null) {
             mMaxAscent = new int[VERTICAL_GRAVITY_COUNT];
@@ -1057,6 +1061,8 @@
                 if (baselineAligned) {
                     final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                     child.measure(freeSpec, freeSpec);
+                } else {
+                    skippedMeasure = true;
                 }
             } else {
                 int oldWidth = Integer.MIN_VALUE;
@@ -1205,9 +1211,10 @@
         widthSize = widthSizeAndState & MEASURED_SIZE_MASK;
         
         // Either expand children with weight to take up available space or
-        // shrink them if they extend beyond our current bounds
+        // shrink them if they extend beyond our current bounds. If we skipped
+        // measurement on any children, we need to measure them now.
         int delta = widthSize - mTotalLength;
-        if (delta != 0 && totalWeight > 0.0f) {
+        if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
             maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index af9e2f0..f7e81b8 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -346,19 +346,24 @@
             return out;
             
         } else if (drawable instanceof BitmapDrawable) {
-            final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
+            final BitmapDrawable bitmap = (BitmapDrawable) drawable;
+            final Bitmap tileBitmap = bitmap.getBitmap();
             if (mSampleTile == null) {
                 mSampleTile = tileBitmap;
             }
-            
-            final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
 
+            final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
             final BitmapShader bitmapShader = new BitmapShader(tileBitmap,
                     Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
             shapeDrawable.getPaint().setShader(bitmapShader);
 
-            return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT,
-                    ClipDrawable.HORIZONTAL) : shapeDrawable;
+            // Ensure the color filter and tint are propagated.
+            shapeDrawable.setTint(bitmap.getTint());
+            shapeDrawable.setTintMode(bitmap.getTintMode());
+            shapeDrawable.setColorFilter(bitmap.getColorFilter());
+
+            return clip ? new ClipDrawable(
+                    shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable;
         }
         
         return drawable;
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 2a5fb15..3d23e4d 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -511,15 +511,18 @@
         if (mOnLayout == null) {
             mOnLayout = makeLayout(mTextOn);
         }
+
         if (mOffLayout == null) {
             mOffLayout = makeLayout(mTextOff);
         }
 
         mTrackDrawable.getPadding(mTempRect);
+
         final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth());
         final int switchWidth = Math.max(mSwitchMinWidth,
                 maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right);
-        final int switchHeight = mTrackDrawable.getIntrinsicHeight();
+        final int switchHeight = Math.max(mTrackDrawable.getIntrinsicHeight(),
+                mThumbDrawable.getIntrinsicHeight());
 
         mThumbWidth = maxTextWidth + mThumbTextPadding * 2;
 
@@ -772,48 +775,51 @@
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
+        final Rect tempRect = mTempRect;
+        final Drawable trackDrawable = mTrackDrawable;
+        final Drawable thumbDrawable = mThumbDrawable;
+
         // Draw the switch
-        int switchLeft = mSwitchLeft;
-        int switchTop = mSwitchTop;
-        int switchRight = mSwitchRight;
-        int switchBottom = mSwitchBottom;
+        final int switchLeft = mSwitchLeft;
+        final int switchTop = mSwitchTop;
+        final int switchRight = mSwitchRight;
+        final int switchBottom = mSwitchBottom;
+        trackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
+        trackDrawable.draw(canvas);
 
-        mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
-        mTrackDrawable.draw(canvas);
+        final int saveCount = canvas.save();
 
-        canvas.save();
-
-        mTrackDrawable.getPadding(mTempRect);
-        int switchInnerLeft = switchLeft + mTempRect.left;
-        int switchInnerTop = switchTop + mTempRect.top;
-        int switchInnerRight = switchRight - mTempRect.right;
-        int switchInnerBottom = switchBottom - mTempRect.bottom;
+        trackDrawable.getPadding(tempRect);
+        final int switchInnerLeft = switchLeft + tempRect.left;
+        final int switchInnerTop = switchTop + tempRect.top;
+        final int switchInnerRight = switchRight - tempRect.right;
+        final int switchInnerBottom = switchBottom - tempRect.bottom;
         canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
 
         // Relies on mTempRect, MUST be called first!
         final int thumbPos = getThumbOffset();
 
-        mThumbDrawable.getPadding(mTempRect);
-        int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos;
-        int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right;
-        mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
-        mThumbDrawable.draw(canvas);
+        thumbDrawable.getPadding(tempRect);
+        int thumbLeft = switchInnerLeft - tempRect.left + thumbPos;
+        int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + tempRect.right;
+        thumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
+        thumbDrawable.draw(canvas);
 
-        // mTextColors should not be null, but just in case
+        final int drawableState[] = getDrawableState();
         if (mTextColors != null) {
-            mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(),
-                    mTextColors.getDefaultColor()));
+            mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0));
         }
-        mTextPaint.drawableState = getDrawableState();
+        mTextPaint.drawableState = drawableState;
 
-        Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
+        final Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
         if (switchText != null) {
-            canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2,
-                    (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2);
+            final int left = (thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2;
+            final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2;
+            canvas.translate(left, top);
             switchText.draw(canvas);
         }
 
-        canvas.restore();
+        canvas.restoreToCount(saveCount);
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 0a80495..cc51a8b 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -57,6 +57,7 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Map;
 
 /**
  * ActionBarImpl is the ActionBar implementation used
@@ -355,6 +356,10 @@
         setSubtitle(mContext.getString(resId));
     }
 
+    public void captureSharedElements(Map<String, View> sharedElements) {
+        mContainerView.findSharedElements(sharedElements);
+    }
+
     public void setSelectedNavigationItem(int position) {
         switch (mActionView.getNavigationMode()) {
         case NAVIGATION_MODE_TABS:
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 1155cbb..3f90f76 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -35,11 +35,12 @@
 
     void noteEvent(int code, String name, int uid);
 
-    void noteStartWakelock(int uid, int pid, String name, int type, boolean unimportantForLogging);
+    void noteStartWakelock(int uid, int pid, String name, String historyName,
+            int type, boolean unimportantForLogging);
     void noteStopWakelock(int uid, int pid, String name, int type);
 
-    void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type,
-            boolean unimportantForLogging);
+    void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, String historyName,
+            int type, boolean unimportantForLogging);
     void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
 
     void noteVibratorOn(int uid, long durationMillis);
@@ -51,7 +52,7 @@
     void noteScreenOff();
     void noteInputEvent();
     void noteUserActivity(int uid, int event);
-    void noteDataConnectionActive(String label, boolean active);
+    void noteDataConnectionActive(int type, boolean active);
     void notePhoneOn();
     void notePhoneOff();
     void notePhoneSignalStrength(in SignalStrength signalStrength);
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 043964f..ec2d654 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -117,7 +117,7 @@
         /** - TODO: Enable when zz_ZY Pseudolocale is complete
          *  if (!localeList.contains("zz_ZY")) {
          *      localeList.add("zz_ZY");
-         *	}
+         *  }
          */
         }
         String[] locales = new String[localeList.size()];
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 2fe2494..a604d84 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -233,7 +233,9 @@
         if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
         while (++mRestorePackage < mRestorePackages.length) {
             String name = mRestorePackages[mRestorePackage].packageName;
-            if (new File(mDataDir, name).isDirectory()) {
+            // skip packages where we have a data dir but no actual contents
+            String[] contents = (new File(mDataDir, name)).list();
+            if (contents != null && contents.length > 0) {
                 if (DEBUG) Log.v(TAG, "  nextRestorePackage() = " + name);
                 return name;
             }
diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java
index 4eff5ac..6ca24d7 100644
--- a/core/java/com/android/internal/os/BatterySipper.java
+++ b/core/java/com/android/internal/os/BatterySipper.java
@@ -34,6 +34,9 @@
     public long wakeLockTime;
     public long mobileRxPackets;
     public long mobileTxPackets;
+    public long mobileActive;
+    public int mobileActiveCount;
+    public double mobilemspp;         // milliseconds per packet
     public long wifiRxPackets;
     public long wifiTxPackets;
     public long mobileRxBytes;
@@ -69,6 +72,11 @@
         return values;
     }
 
+    public void computeMobilemspp() {
+        long packets = mobileRxPackets+mobileTxPackets;
+        mobilemspp = packets > 0 ? (mobileActive / (double)packets) : 0;
+    }
+
     @Override
     public int compareTo(BatterySipper other) {
         // Return the flipped value because we want the items in descending order
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 8a15c99..6f95937 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -43,6 +43,7 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
@@ -73,6 +74,8 @@
             = new SparseArray<List<BatterySipper>>();
     private final SparseArray<Double> mUserPower = new SparseArray<Double>();
 
+    private final List<BatterySipper> mMobilemsppList = new ArrayList<BatterySipper>();
+
     private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
     private int mAsUser = 0;
 
@@ -90,6 +93,9 @@
     private double mMinDrainedPower;
     private double mMaxDrainedPower;
 
+    // How much the apps together have kept the mobile radio active.
+    private long mAppMobileActive;
+
     // How much the apps together have left WIFI running.
     private long mAppWifiRunning;
 
@@ -132,7 +138,7 @@
     }
 
     public static String makemAh(double power) {
-        if (power < .0001) return String.format("%.8f", power);
+        if (power < .00001) return String.format("%.8f", power);
         else if (power < .0001) return String.format("%.7f", power);
         else if (power < .001) return String.format("%.6f", power);
         else if (power < .01) return String.format("%.5f", power);
@@ -160,6 +166,7 @@
         mTotalPower = 0;
         mWifiPower = 0;
         mBluetoothPower = 0;
+        mAppMobileActive = 0;
         mAppWifiRunning = 0;
 
         mUsageList.clear();
@@ -167,6 +174,7 @@
         mBluetoothSippers.clear();
         mUserSippers.clear();
         mUserPower.clear();
+        mMobilemsppList.clear();
 
         if (mStats == null) {
             return;
@@ -193,6 +201,37 @@
                 * mPowerProfile.getBatteryCapacity()) / 100;
 
         processAppUsage();
+
+        // Before aggregating apps in to users, collect all apps to sort by their ms per packet.
+        for (int i=0; i<mUsageList.size(); i++) {
+            BatterySipper bs = mUsageList.get(i);
+            bs.computeMobilemspp();
+            if (bs.mobilemspp != 0) {
+                mMobilemsppList.add(bs);
+            }
+        }
+        for (int i=0; i<mUserSippers.size(); i++) {
+            List<BatterySipper> user = mUserSippers.valueAt(i);
+            for (int j=0; j<user.size(); j++) {
+                BatterySipper bs = user.get(j);
+                bs.computeMobilemspp();
+                if (bs.mobilemspp != 0) {
+                    mMobilemsppList.add(bs);
+                }
+            }
+        }
+        Collections.sort(mMobilemsppList, new Comparator<BatterySipper>() {
+            @Override
+            public int compare(BatterySipper lhs, BatterySipper rhs) {
+                if (lhs.mobilemspp < rhs.mobilemspp) {
+                    return 1;
+                } else if (lhs.mobilemspp > rhs.mobilemspp) {
+                    return -1;
+                }
+                return 0;
+            }
+        });
+
         processMiscUsage();
 
         if (DEBUG) {
@@ -225,6 +264,7 @@
             powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
         }
         final double mobilePowerPerPacket = getMobilePowerPerPacket();
+        final double mobilePowerPerMs = getMobilePowerPerMs();
         final double wifiPowerPerPacket = getWifiPowerPerPacket();
         long appWakelockTime = 0;
         BatterySipper osApp = null;
@@ -320,9 +360,20 @@
             final long mobileTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
             final long mobileRxB = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType);
             final long mobileTxB = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType);
-            p = (mobileRx + mobileTx) * mobilePowerPerPacket;
+            final long mobileActive = u.getMobileRadioActiveTime(mStatsType);
+            if (mobileActive > 0) {
+                // We are tracking when the radio is up, so can use the active time to
+                // determine power use.
+                mAppMobileActive += mobileActive;
+                p = (mobilePowerPerMs * mobileActive) / 1000;
+            } else {
+                // We are not tracking when the radio is up, so must approximate power use
+                // based on the number of packets.
+                p = (mobileRx + mobileTx) * mobilePowerPerPacket;
+            }
             if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": mobile packets "
-                    + (mobileRx+mobileTx) + " power=" + makemAh(p));
+                    + (mobileRx+mobileTx) + " active time " + mobileActive
+                    + " power=" + makemAh(p));
             power += p;
 
             // Add cost of wifi traffic
@@ -406,6 +457,8 @@
                 app.wakeLockTime = wakelockTime;
                 app.mobileRxPackets = mobileRx;
                 app.mobileTxPackets = mobileTx;
+                app.mobileActive = mobileActive / 1000;
+                app.mobileActiveCount = u.getMobileRadioActiveCount(mStatsType);
                 app.wifiRxPackets = wifiRx;
                 app.wifiTxPackets = wifiTx;
                 app.mobileRxBytes = mobileRxB;
@@ -474,7 +527,7 @@
         double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
                 * phoneOnTimeMs / (60*60*1000);
         if (phoneOnPower != 0) {
-            addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
+            BatterySipper bs = addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
         }
     }
 
@@ -531,12 +584,19 @@
             Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + makemAh(p));
         }
         power += p;
+        long radioActiveTimeUs = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType);
+        long remainingActiveTime = (radioActiveTimeUs - mAppMobileActive) / 1000;
+        if (remainingActiveTime > 0) {
+            power += getMobilePowerPerMs() * remainingActiveTime;
+        }
         if (power != 0) {
             BatterySipper bs =
                     addEntry(BatterySipper.DrainType.CELL, signalTimeMs, power);
             if (signalTimeMs != 0) {
                 bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
             }
+            bs.mobileActive = remainingActiveTime;
+            bs.mobileActiveCount = mStats.getMobileRadioActiveUnknownCount(mStatsType);
         }
     }
 
@@ -551,6 +611,8 @@
             bs.wakeLockTime += wbs.wakeLockTime;
             bs.mobileRxPackets += wbs.mobileRxPackets;
             bs.mobileTxPackets += wbs.mobileTxPackets;
+            bs.mobileActive += wbs.mobileActive;
+            bs.mobileActiveCount += wbs.mobileActiveCount;
             bs.wifiRxPackets += wbs.wifiRxPackets;
             bs.wifiTxPackets += wbs.wifiTxPackets;
             bs.mobileRxBytes += wbs.mobileRxBytes;
@@ -558,6 +620,7 @@
             bs.wifiRxBytes += wbs.wifiRxBytes;
             bs.wifiTxBytes += wbs.wifiTxBytes;
         }
+        bs.computeMobilemspp();
     }
 
     private void addWiFiUsage() {
@@ -642,14 +705,21 @@
 
         final long radioDataUptimeMs
                 = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType) / 1000;
-        final double mobilePps = radioDataUptimeMs != 0
-                ? mobileData / (double)radioDataUptimeMs
+        final double mobilePps = (mobileData != 0 && radioDataUptimeMs != 0)
+                ? (mobileData / (double)radioDataUptimeMs)
                 : (((double)MOBILE_BPS) / 8 / 2048);
 
         return (MOBILE_POWER / mobilePps) / (60*60);
     }
 
     /**
+     * Return estimated power (in mAs) of keeping the radio up
+     */
+    private double getMobilePowerPerMs() {
+        return mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) / (60*60*1000);
+    }
+
+    /**
      * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
      */
     private double getWifiPowerPerPacket() {
@@ -691,6 +761,10 @@
         return mUsageList;
     }
 
+    public List<BatterySipper> getMobilemsppList() {
+        return mMobilemsppList;
+    }
+
     public long getStatsPeriod() { return mStatsPeriod; }
 
     public int getStatsType() { return mStatsType; };
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index c3e9862..fdb090b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -56,7 +56,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.JournaledFile;
-import com.google.android.collect.Sets;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -65,7 +64,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -89,7 +87,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 85 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 94 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -285,6 +283,9 @@
 
     boolean mMobileRadioActive;
     StopwatchTimer mMobileRadioActiveTimer;
+    StopwatchTimer mMobileRadioActivePerAppTimer;
+    LongSamplingCounter mMobileRadioActiveUnknownTime;
+    LongSamplingCounter mMobileRadioActiveUnknownCount;
 
     /** Bluetooth headset object */
     BluetoothHeadset mBtHeadset;
@@ -372,8 +373,10 @@
             new HashMap<String, KernelWakelockStats>();
 
     private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
-    private NetworkStats mLastMobileSnapshot;
-    private NetworkStats mLastWifiSnapshot;
+    private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mLastMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mCurWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mLastWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
     private NetworkStats mTmpNetworkStats;
     private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
 
@@ -1176,11 +1179,12 @@
 
         void startRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
             if (mNesting++ == 0) {
-                mUpdateTime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
+                final long batteryRealtime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
+                mUpdateTime = batteryRealtime;
                 if (mTimerPool != null) {
                     // Accumulate time to all currently active timers before adding
                     // this new one to the pool.
-                    refreshTimersLocked(stats, mTimerPool);
+                    refreshTimersLocked(stats, batteryRealtime, mTimerPool, null);
                     // Add this timer to the active pool
                     mTimerPool.add(this);
                 }
@@ -1199,21 +1203,35 @@
             return mNesting > 0;
         }
 
+        long checkpointRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
+            if (mNesting > 0) {
+                // We are running...
+                final long batteryRealtime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
+                if (mTimerPool != null) {
+                    return refreshTimersLocked(stats, batteryRealtime, mTimerPool, this);
+                }
+                final long heldTime = batteryRealtime - mUpdateTime;
+                mUpdateTime = batteryRealtime;
+                mTotalTime += heldTime;
+                return heldTime;
+            }
+            return 0;
+        }
+
         void stopRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
             // Ignore attempt to stop a timer that isn't running
             if (mNesting == 0) {
                 return;
             }
             if (--mNesting == 0) {
+                final long batteryRealtime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
                 if (mTimerPool != null) {
                     // Accumulate time to all active counters, scaled by the total
                     // active in the pool, before taking this one out of the pool.
-                    refreshTimersLocked(stats, mTimerPool);
+                    refreshTimersLocked(stats, batteryRealtime, mTimerPool, null);
                     // Remove this timer from the active pool
                     mTimerPool.remove(this);
                 } else {
-                    final long batteryRealtime = stats.getBatteryRealtimeLocked(
-                            elapsedRealtime * 1000);
                     mNesting = 1;
                     mTotalTime = computeRunTimeLocked(batteryRealtime);
                     mNesting = 0;
@@ -1235,19 +1253,23 @@
 
         // Update the total time for all other running Timers with the same type as this Timer
         // due to a change in timer count
-        private static void refreshTimersLocked(final BatteryStatsImpl stats,
-                final ArrayList<StopwatchTimer> pool) {
-            final long realtime = SystemClock.elapsedRealtime() * 1000;
-            final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
+        private static long refreshTimersLocked(final BatteryStatsImpl stats,
+                long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
+            long selfTime = 0;
             final int N = pool.size();
             for (int i=N-1; i>= 0; i--) {
                 final StopwatchTimer t = pool.get(i);
                 long heldTime = batteryRealtime - t.mUpdateTime;
                 if (heldTime > 0) {
-                    t.mTotalTime += heldTime / N;
+                    final long myTime = heldTime / N;
+                    if (t == self) {
+                        selfTime = myTime;
+                    }
+                    t.mTotalTime += myTime;
                 }
                 t.mUpdateTime = batteryRealtime;
             }
+            return selfTime;
         }
 
         @Override
@@ -2011,7 +2033,7 @@
         addHistoryEventLocked(SystemClock.elapsedRealtime(), code, name, uid);
     }
 
-    public void noteStartWakeLocked(int uid, int pid, String name, int type,
+    public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
             boolean unimportantForLogging) {
         uid = mapUid(uid);
         final long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -2023,7 +2045,7 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
                 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                mHistoryCur.wakelockTag.string = name;
+                mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
                 mHistoryCur.wakelockTag.uid = uid;
                 mWakeLockImportant = !unimportantForLogging;
                 addHistoryRecordLocked(elapsedRealtime);
@@ -2032,7 +2054,7 @@
                     // We'll try to update the last tag.
                     mHistoryLastWritten.wakelockTag = null;
                     mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                    mHistoryCur.wakelockTag.string = name;
+                    mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
                     mHistoryCur.wakelockTag.uid = uid;
                     addHistoryRecordLocked(elapsedRealtime);
                 }
@@ -2070,11 +2092,11 @@
         }
     }
 
-    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type,
-            boolean unimportantForLogging) {
+    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
+            String historyName, int type, boolean unimportantForLogging) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStartWakeLocked(ws.get(i), pid, name, type, unimportantForLogging);
+            noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging);
         }
     }
 
@@ -2291,7 +2313,8 @@
 
             // Fake a wake lock, so we consider the device waked as long
             // as the screen is on.
-            noteStartWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL, false);
+            noteStartWakeLocked(Process.myUid(), Process.myPid(), "screen", null,
+                    WAKE_TYPE_PARTIAL, false);
             
             // Update discharge amounts.
             if (mOnBatteryInternal) {
@@ -2351,29 +2374,31 @@
     }
 
     public void noteUserActivityLocked(int uid, int event) {
-        uid = mapUid(uid);
-        getUidStatsLocked(uid).noteUserActivityLocked(event);
+        if (mOnBatteryInternal) {
+            uid = mapUid(uid);
+            getUidStatsLocked(uid).noteUserActivityLocked(event);
+        }
     }
 
-    public void noteDataConnectionActive(String label, boolean active) {
-        try {
-            int type = Integer.parseInt(label);
-            if (ConnectivityManager.isNetworkTypeMobile(type)) {
-                final long elapsedRealtime = SystemClock.elapsedRealtime();
-                if (mMobileRadioActive != active) {
-                    if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
-                    else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
-                    if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
-                            + Integer.toHexString(mHistoryCur.states));
-                    addHistoryRecordLocked(elapsedRealtime);
-                    mMobileRadioActive = active;
-                    if (active) mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
-                    else mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
+    public void noteDataConnectionActive(int type, boolean active) {
+        if (ConnectivityManager.isNetworkTypeMobile(type)) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            if (mMobileRadioActive != active) {
+                if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
+                        + Integer.toHexString(mHistoryCur.states));
+                addHistoryRecordLocked(elapsedRealtime);
+                mMobileRadioActive = active;
+                if (active) {
+                    mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
+                    mMobileRadioActivePerAppTimer.startRunningLocked(this, elapsedRealtime);
+                } else {
+                    updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime);
+                    mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
+                    mMobileRadioActivePerAppTimer.stopRunningLocked(this, elapsedRealtime);
                 }
             }
-        } catch (NumberFormatException e) {
-            Slog.w(TAG, "Bad data connection label: " + label, e);
-            return;
         }
     }
 
@@ -3005,13 +3030,17 @@
         // During device boot, qtaguid isn't enabled until after the inital
         // loading of battery stats. Now that they're enabled, take our initial
         // snapshot for future delta calculation.
-        updateNetworkActivityLocked();
+        updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
     }
 
     @Override public long getScreenOnTime(long batteryRealtime, int which) {
         return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
     }
 
+    @Override public int getScreenOnCount(int which) {
+        return mScreenOnTimer.getCountLocked(which);
+    }
+
     @Override public long getScreenBrightnessTime(int brightnessBin,
             long batteryRealtime, int which) {
         return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
@@ -3026,6 +3055,10 @@
         return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
     }
 
+    @Override public int getPhoneOnCount(int which) {
+        return mPhoneOnTimer.getCountLocked(which);
+    }
+
     @Override public long getPhoneSignalStrengthTime(int strengthBin,
             long batteryRealtime, int which) {
         return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
@@ -3056,6 +3089,18 @@
         return mMobileRadioActiveTimer.getTotalTimeLocked(batteryRealtime, which);
     }
 
+    @Override public int getMobileRadioActiveCount(int which) {
+        return mMobileRadioActiveTimer.getCountLocked(which);
+    }
+
+    @Override public long getMobileRadioActiveUnknownTime(int which) {
+        return mMobileRadioActiveUnknownTime.getCountLocked(which);
+    }
+
+    @Override public int getMobileRadioActiveUnknownCount(int which) {
+        return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
+    }
+
     @Override public long getWifiOnTime(long batteryRealtime, int which) {
         return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
     }
@@ -3155,6 +3200,8 @@
 
         LongSamplingCounter[] mNetworkByteActivityCounters;
         LongSamplingCounter[] mNetworkPacketActivityCounters;
+        LongSamplingCounter mMobileRadioActiveTime;
+        LongSamplingCounter mMobileRadioActiveCount;
 
         /**
          * The statistics we have collected for this uid's wake locks.
@@ -3555,6 +3602,14 @@
             }
         }
 
+        void noteMobileRadioActiveTimeLocked(long batteryUptime) {
+            if (mNetworkByteActivityCounters == null) {
+                initNetworkActivityLocked();
+            }
+            mMobileRadioActiveTime.addCountLocked(batteryUptime);
+            mMobileRadioActiveCount.addCountLocked(1);
+        }
+
         @Override
         public boolean hasNetworkActivity() {
             return mNetworkByteActivityCounters != null;
@@ -3580,6 +3635,18 @@
             }
         }
 
+        @Override
+        public long getMobileRadioActiveTime(int which) {
+            return mMobileRadioActiveTime != null
+                    ? mMobileRadioActiveTime.getCountLocked(which) : 0;
+        }
+
+        @Override
+        public int getMobileRadioActiveCount(int which) {
+            return mMobileRadioActiveCount != null
+                    ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
+        }
+
         void initNetworkActivityLocked() {
             mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
             mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
@@ -3587,6 +3654,8 @@
                 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
                 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
             }
+            mMobileRadioActiveTime = new LongSamplingCounter(mUnpluggables);
+            mMobileRadioActiveCount = new LongSamplingCounter(mUnpluggables);
         }
 
         /**
@@ -3651,6 +3720,8 @@
                     mNetworkByteActivityCounters[i].reset(false);
                     mNetworkPacketActivityCounters[i].reset(false);
                 }
+                mMobileRadioActiveTime.reset(false);
+                mMobileRadioActiveCount.reset(false);
             }
 
             if (mWakelockStats.size() > 0) {
@@ -3858,6 +3929,8 @@
                     mNetworkByteActivityCounters[i].writeToParcel(out);
                     mNetworkPacketActivityCounters[i].writeToParcel(out);
                 }
+                mMobileRadioActiveTime.writeToParcel(out);
+                mMobileRadioActiveCount.writeToParcel(out);
             } else {
                 out.writeInt(0);
             }
@@ -3981,6 +4054,8 @@
                     mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
                     mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
                 }
+                mMobileRadioActiveTime = new LongSamplingCounter(mUnpluggables, in);
+                mMobileRadioActiveCount = new LongSamplingCounter(mUnpluggables, in);
             } else {
                 mNetworkByteActivityCounters = null;
                 mNetworkPacketActivityCounters = null;
@@ -5075,6 +5150,9 @@
             mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
         }
         mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables);
+        mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mUnpluggables);
+        mMobileRadioActiveUnknownTime = new LongSamplingCounter(mUnpluggables);
+        mMobileRadioActiveUnknownCount = new LongSamplingCounter(mUnpluggables);
         mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
         mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
         for (int i=0; i<NUM_WIFI_STATES; i++) {
@@ -5341,6 +5419,9 @@
             mNetworkPacketActivityCounters[i].reset(false);
         }
         mMobileRadioActiveTimer.reset(this, false);
+        mMobileRadioActivePerAppTimer.reset(this, false);
+        mMobileRadioActiveUnknownTime.reset(false);
+        mMobileRadioActiveUnknownCount.reset(false);
         mWifiOnTimer.reset(this, false);
         mGlobalWifiRunningTimer.reset(this, false);
         for (int i=0; i<NUM_WIFI_STATES; i++) {
@@ -5418,7 +5499,10 @@
 
     public void pullPendingStateUpdatesLocked() {
         updateKernelWakelocksLocked();
-        updateNetworkActivityLocked();
+        updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
+        if (mOnBatteryInternal) {
+            updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
+        }
     }
 
     void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
@@ -5603,11 +5687,16 @@
         }
     }
 
-    private void updateNetworkActivityLocked() {
+    static final int NET_UPDATE_MOBILE = 1<<0;
+    static final int NET_UPDATE_WIFI = 1<<1;
+    static final int NET_UPDATE_ALL = 0xffff;
+
+    private void updateNetworkActivityLocked(int which, long elapsedRealtime) {
         if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
 
-        if (mMobileIfaces.length > 0) {
+        if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
             final NetworkStats snapshot;
+            final NetworkStats last = mCurMobileSnapshot;
             try {
                 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
                         mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
@@ -5616,39 +5705,62 @@
                 return;
             }
 
-            if (mLastMobileSnapshot == null) {
-                mLastMobileSnapshot = snapshot;
-                return;
-            }
+            mCurMobileSnapshot = snapshot;
+            mLastMobileSnapshot = last;
 
-            final NetworkStats delta = NetworkStats.subtract(snapshot, mLastMobileSnapshot,
-                    null, null, mTmpNetworkStats);
-            mTmpNetworkStats = delta;
-            mLastMobileSnapshot = snapshot;
+            if (mOnBatteryInternal) {
+                final NetworkStats delta = NetworkStats.subtract(snapshot, last,
+                        null, null, mTmpNetworkStats);
+                mTmpNetworkStats = delta;
 
-            final int size = delta.size();
-            for (int i = 0; i < size; i++) {
-                final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+                long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(this,
+                        elapsedRealtime);
+                long totalPackets = delta.getTotalPackets();
 
-                if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
+                final int size = delta.size();
+                for (int i = 0; i < size; i++) {
+                    final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
 
-                final Uid u = getUidStatsLocked(entry.uid);
-                u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
-                        entry.rxPackets);
-                u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
-                        entry.txPackets);
+                    if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
-                mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(entry.rxBytes);
-                mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(entry.txBytes);
-                mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
-                        entry.rxPackets);
-                mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
-                        entry.txPackets);
+                    final Uid u = getUidStatsLocked(entry.uid);
+                    u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
+                            entry.rxPackets);
+                    u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
+                            entry.txPackets);
+
+                    if (radioTime > 0) {
+                        // Distribute total radio active time in to this app.
+                        long appPackets = entry.rxPackets + entry.txPackets;
+                        long appRadioTime = (radioTime*appPackets)/totalPackets;
+                        u.noteMobileRadioActiveTimeLocked(appRadioTime);
+                        // Remove this app from the totals, so that we don't lose any time
+                        // due to rounding.
+                        radioTime -= appRadioTime;
+                        totalPackets -= appPackets;
+                    }
+
+                    mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+                            entry.rxBytes);
+                    mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+                            entry.txBytes);
+                    mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+                            entry.rxPackets);
+                    mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+                            entry.txPackets);
+                }
+
+                if (radioTime > 0) {
+                    // Whoops, there is some radio time we can't blame on an app!
+                    mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
+                    mMobileRadioActiveUnknownCount.addCountLocked(1);
+                }
             }
         }
 
-        if (mWifiIfaces.length > 0) {
+        if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
             final NetworkStats snapshot;
+            final NetworkStats last = mCurWifiSnapshot;
             try {
                 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
                         mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
@@ -5657,32 +5769,42 @@
                 return;
             }
 
-            if (mLastWifiSnapshot == null) {
-                mLastWifiSnapshot = snapshot;
-                return;
-            }
+            mCurWifiSnapshot = snapshot;
+            mLastWifiSnapshot = last;
 
-            final NetworkStats delta = NetworkStats.subtract(snapshot, mLastWifiSnapshot,
-                    null, null, mTmpNetworkStats);
-            mTmpNetworkStats = delta;
-            mLastWifiSnapshot = snapshot;
+            if (mOnBatteryInternal) {
+                final NetworkStats delta = NetworkStats.subtract(snapshot, last,
+                        null, null, mTmpNetworkStats);
+                mTmpNetworkStats = delta;
 
-            final int size = delta.size();
-            for (int i = 0; i < size; i++) {
-                final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+                final int size = delta.size();
+                for (int i = 0; i < size; i++) {
+                    final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
 
-                if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
+                    if (DEBUG) {
+                        final NetworkStats.Entry cur = snapshot.getValues(i, null);
+                        Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+                                + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
+                                + " tx=" + cur.txBytes);
+                    }
 
-                final Uid u = getUidStatsLocked(entry.uid);
-                u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, entry.rxPackets);
-                u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, entry.txPackets);
+                    if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
-                mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(entry.rxBytes);
-                mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(entry.txBytes);
-                mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
-                        entry.rxPackets);
-                mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
-                        entry.txPackets);
+                    final Uid u = getUidStatsLocked(entry.uid);
+                    u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
+                            entry.rxPackets);
+                    u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
+                            entry.txPackets);
+
+                    mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+                            entry.rxBytes);
+                    mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+                            entry.txBytes);
+                    mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+                            entry.rxPackets);
+                    mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+                            entry.txPackets);
+                }
             }
         }
     }
@@ -6271,6 +6393,9 @@
         }
         mMobileRadioActive = false;
         mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
+        mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
+        mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
+        mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
         mWifiOn = false;
         mWifiOnTimer.readSummaryFromParcelLocked(in);
         mGlobalWifiRunning = false;
@@ -6366,6 +6491,8 @@
                     u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
                     u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
                 }
+                u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
+                u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
             }
 
             int NW = in.readInt();
@@ -6502,6 +6629,9 @@
             mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
         }
         mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
+        mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
         mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         for (int i=0; i<NUM_WIFI_STATES; i++) {
@@ -6605,6 +6735,8 @@
                     u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
                     u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
                 }
+                u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
+                u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
             }
 
             int NW = u.mWakelockStats.size();
@@ -6744,6 +6876,9 @@
         }
         mMobileRadioActive = false;
         mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables, in);
+        mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mUnpluggables, in);
+        mMobileRadioActiveUnknownTime = new LongSamplingCounter(mUnpluggables, in);
+        mMobileRadioActiveUnknownCount = new LongSamplingCounter(mUnpluggables, in);
         mWifiOn = false;
         mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
         mGlobalWifiRunning = false;
@@ -6861,6 +6996,9 @@
             mNetworkPacketActivityCounters[i].writeToParcel(out);
         }
         mMobileRadioActiveTimer.writeToParcel(out, batteryRealtime);
+        mMobileRadioActivePerAppTimer.writeToParcel(out, batteryRealtime);
+        mMobileRadioActiveUnknownTime.writeToParcel(out);
+        mMobileRadioActiveUnknownCount.writeToParcel(out);
         mWifiOnTimer.writeToParcel(out, batteryRealtime);
         mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
         for (int i=0; i<NUM_WIFI_STATES; i++) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index bf62745..05c57e8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -244,9 +244,11 @@
     }
 
     static void preload() {
+        Log.d(TAG, "begin preload");
         preloadClasses();
         preloadResources();
         preloadOpenGL();
+        Log.d(TAG, "end preload");
     }
 
     private static void preloadOpenGL() {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 5056c57..a09c314 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -164,9 +164,8 @@
 	$(TOP)/frameworks/av/include \
 	$(TOP)/system/media/camera/include \
 	external/skia/src/core \
-	external/skia/src/pdf \
+	external/skia/src/effects \
 	external/skia/src/images \
-	external/skia/include/utils \
 	external/sqlite/dist \
 	external/sqlite/android \
 	external/expat/lib \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index fae93ba..e8feacb 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -125,12 +125,18 @@
 static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
         int sampleSize, bool ditherImage) {
 
+    SkImageInfo bitmapInfo;
+    if (!bitmap->asImageInfo(&bitmapInfo)) {
+        ALOGW("bitmap has unknown configuration so no memory has been allocated");
+        return NULL;
+    }
+
     SkImageRef* pr;
     // only use ashmem for large images, since mmaps come at a price
     if (bitmap->getSize() >= 32 * 1024) {
-        pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize);
+        pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize);
     } else {
-        pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize);
+        pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize);
     }
     pr->setDitherImage(ditherImage);
     bitmap->setPixelRef(pr)->unref();
@@ -192,8 +198,15 @@
             return false;
         }
 
+        SkImageInfo bitmapInfo;
+        if (!bitmap->asImageInfo(&bitmapInfo)) {
+            ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
+            return false;
+        }
+
         // Create a new pixelref with the new ctable that wraps the previous pixelref
-        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable);
+        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef),
+                bitmapInfo, bitmap->rowBytes(), ctable);
 
         bitmap->setPixelRef(pr)->unref();
         // since we're already allocated, we lockPixels right away
@@ -418,7 +431,7 @@
         }
 
         SkPaint paint;
-        paint.setFilterBitmap(true);
+        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
 
         SkCanvas canvas(*outputBitmap);
         canvas.scale(sx, sy);
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index e98d45b..7420055 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -555,7 +555,7 @@
                 if (paint) {
                     filteredPaint = *paint;
                 }
-                filteredPaint.setFilterBitmap(true);
+                filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
                 canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
             } else {
                 canvas->drawBitmap(*bitmap, left_, top_, paint);
@@ -570,7 +570,7 @@
             if (paint) {
                 filteredPaint = *paint;
             }
-            filteredPaint.setFilterBitmap(true);
+            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
 
             canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
 
@@ -593,7 +593,7 @@
             if (paint) {
                 filteredPaint = *paint;
             }
-            filteredPaint.setFilterBitmap(true);
+            filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
             canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
         } else {
             canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 66f9f3d..98edbdb 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -444,8 +444,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
-        SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
+AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage,
+        size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) :
+        SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
         fWrappedPixelRef(NULL) {
     SkASSERT(storage);
     SkASSERT(env);
@@ -463,10 +464,11 @@
 
 }
 
-AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
-        SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
+AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+        size_t rowBytes, SkColorTable* ctable) :
+        SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false),
         fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
-            wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
+                wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
 {
     SkASSERT(fWrappedPixelRef);
     SkSafeRef(fWrappedPixelRef);
@@ -568,6 +570,14 @@
                           "bitmap size exceeds 32bits");
         return NULL;
     }
+
+    SkImageInfo bitmapInfo;
+    if (!bitmap->asImageInfo(&bitmapInfo)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                "unknown bitmap configuration");
+        return NULL;
+    }
+
     size_t size = size64.get32();
     jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
                                                              gVMRuntime_newNonMovableArray,
@@ -581,7 +591,8 @@
         return NULL;
     }
     SkASSERT(addr);
-    SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
+    SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr,
+            bitmap->rowBytes(), arrayObj, ctable);
     bitmap->setPixelRef(pr)->unref();
     // since we're already allocated, we lockPixels right away
     // HeapAllocator behaves this way too
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 5f29604..cb154aa 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -92,15 +92,16 @@
 
 class AndroidPixelRef : public SkMallocPixelRef {
 public:
-    AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
-                    SkColorTable* ctable);
+    AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes,
+            jbyteArray storageObj, SkColorTable* ctable);
 
     /**
      * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
      * the same storage and java byte array refcounting, yet have a different
      * color table.
      */
-    AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable);
+    AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+            size_t rowBytes, SkColorTable* ctable);
 
     virtual ~AndroidPixelRef();
 
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index f331af7..5573366 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -1,5 +1,6 @@
 #include "GraphicsJNI.h"
 #include "SkMaskFilter.h"
+#include "SkBlurMask.h"
 #include "SkBlurMaskFilter.h"
 #include "SkTableMaskFilter.h"
 
@@ -19,8 +20,9 @@
     }
 
     static jlong createBlur(JNIEnv* env, jobject, jfloat radius, jint blurStyle) {
-        SkMaskFilter* filter = SkBlurMaskFilter::Create(SkFloatToScalar(radius),
-                                        (SkBlurMaskFilter::BlurStyle)blurStyle);
+        SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkFloatToScalar(radius));
+        SkMaskFilter* filter = SkBlurMaskFilter::Create(
+                (SkBlurMaskFilter::BlurStyle)blurStyle, sigma);
         ThrowIAE_IfNull(env, filter);
         return reinterpret_cast<jlong>(filter);
     }
@@ -34,10 +36,9 @@
             direction[i] = SkFloatToScalar(values[i]);
         }
 
-        SkMaskFilter* filter =  SkBlurMaskFilter::CreateEmboss(direction,
-                                                      SkFloatToScalar(ambient),
-                                                      SkFloatToScalar(specular),
-                                                      SkFloatToScalar(radius));
+        SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkFloatToScalar(radius));
+        SkMaskFilter* filter =  SkBlurMaskFilter::CreateEmboss(sigma,
+                direction, SkFloatToScalar(ambient), SkFloatToScalar(specular));
         ThrowIAE_IfNull(env, filter);
         return reinterpret_cast<jlong>(filter);
     }
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 6c81f06..189fe47 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -155,7 +155,8 @@
 
     static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
         NPE_CHECK_RETURN_VOID(env, paint);
-        GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
+        GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
+                filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
     }
 
     static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 6bbf45a..429f177 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -25,7 +25,7 @@
 #include <android_runtime/AndroidRuntime.h>
 
 #include "SkPath.h"
-#include "pathops/SkPathOps.h"
+#include "SkPathOps.h"
 
 #include <Caches.h>
 #include <vector>
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index bcf1273..912968a 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -214,7 +214,7 @@
 
     SkRegion* region = new SkRegion;
     size_t size = p->readInt32();
-    region->readFromMemory(p->readInplace(size));
+    region->readFromMemory(p->readInplace(size), size);
 
     return reinterpret_cast<jlong>(region);
 }
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 3047440..1fe6358 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -520,7 +520,7 @@
     SkiaShader* shaderB = reinterpret_cast<SkiaShader *>(shaderBHandle);
     SkXfermode* mode = reinterpret_cast<SkXfermode *>(modeHandle);
     SkXfermode::Mode skiaMode;
-    if (!SkXfermode::IsMode(mode, &skiaMode)) {
+    if (!SkXfermode::AsMode(mode, &skiaMode)) {
         // TODO: Support other modes
         skiaMode = SkXfermode::kSrcOver_Mode;
     }
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index a17f328..a91c622 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -27,7 +27,7 @@
 #include <GLES/gl.h>
 #include <ETC1/etc1.h>
 
-#include <core/SkBitmap.h>
+#include <SkBitmap.h>
 
 #include "android_runtime/AndroidRuntime.h"
 
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
index c10b963f..467a9a1 100644
--- a/core/jni/android_hardware_UsbDeviceConnection.cpp
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -123,20 +123,45 @@
     return (ret == 0) ? JNI_TRUE : JNI_FALSE;
 }
 
-static jint
+static jboolean
 android_hardware_UsbDeviceConnection_release_interface(JNIEnv *env, jobject thiz, jint interfaceID)
 {
     struct usb_device* device = get_device_from_object(env, thiz);
     if (!device) {
         ALOGE("device is closed in native_release_interface");
-        return -1;
+        return JNI_FALSE;
     }
     int ret = usb_device_release_interface(device, interfaceID);
     if (ret == 0) {
         // allow kernel to reconnect its driver
         usb_device_connect_kernel_driver(device, interfaceID, true);
     }
-    return ret;
+    return (ret == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean
+android_hardware_UsbDeviceConnection_set_interface(JNIEnv *env, jobject thiz, jint interfaceID,
+        jint alternateSetting)
+{
+    struct usb_device* device = get_device_from_object(env, thiz);
+    if (!device) {
+        ALOGE("device is closed in native_set_interface");
+        return JNI_FALSE;
+    }
+    int ret = usb_device_set_interface(device, interfaceID, alternateSetting);
+    return (ret == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean
+android_hardware_UsbDeviceConnection_set_configuration(JNIEnv *env, jobject thiz, jint configurationID)
+{
+    struct usb_device* device = get_device_from_object(env, thiz);
+    if (!device) {
+        ALOGE("device is closed in native_set_configuration");
+        return JNI_FALSE;
+    }
+    int ret = usb_device_set_configuration(device, configurationID);
+    return (ret == 0) ? JNI_TRUE : JNI_FALSE;
 }
 
 static jint
@@ -229,6 +254,8 @@
     {"native_get_desc",         "()[B", (void *)android_hardware_UsbDeviceConnection_get_desc},
     {"native_claim_interface",  "(IZ)Z",(void *)android_hardware_UsbDeviceConnection_claim_interface},
     {"native_release_interface","(I)Z", (void *)android_hardware_UsbDeviceConnection_release_interface},
+    {"native_set_interface","(II)Z",    (void *)android_hardware_UsbDeviceConnection_set_interface},
+    {"native_set_configuration","(I)Z", (void *)android_hardware_UsbDeviceConnection_set_configuration},
     {"native_control_request",  "(IIII[BIII)I",
                                         (void *)android_hardware_UsbDeviceConnection_control_request},
     {"native_bulk_request",     "(I[BIII)I",
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 9c357de..0132b5f 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -18,6 +18,7 @@
 
 #define LOG_TAG "AudioRecord-JNI"
 
+#include <inttypes.h>
 #include <jni.h>
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
@@ -311,7 +312,7 @@
     if (lpRecorder == NULL) {
         return;
     }
-    ALOGV("About to delete lpRecorder: %x\n", (int)lpRecorder.get());
+    ALOGV("About to delete lpRecorder: %" PRIxPTR "\n", lpRecorder.get());
     lpRecorder->stop();
 
     audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetLongField(
@@ -324,7 +325,7 @@
     // delete the callback information
     if (lpCookie) {
         Mutex::Autolock l(sLock);
-        ALOGV("deleting lpCookie: %x\n", (int)lpCookie);
+        ALOGV("deleting lpCookie: %" PRIxPTR "\n", lpCookie);
         while (lpCookie->busy) {
             if (lpCookie->cond.waitRelative(sLock,
                                             milliseconds(CALLBACK_COND_WAIT_TIMEOUT_MS)) !=
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 8c7b34a..7e958e7 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -263,7 +263,7 @@
 
     // compute the frame count
     const size_t bytesPerSample = audio_bytes_per_sample(format);
-    int frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);
+    size_t frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);
 
     jclass clazz = env->GetObjectClass(thiz);
     if (clazz == NULL) {
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 5b0a4b2..19e4d99 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -69,22 +69,22 @@
     jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
     eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
 
-    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I");
-    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I");
-    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I");
-    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I");
+    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J");
+    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getNativeHandle", "()J");
+    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J");
+    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getNativeHandle", "()J");
 
 
-    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(I)V");
-    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(I)V");
-    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(I)V");
-    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(I)V");
+    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(J)V");
+    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(J)V");
+    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(J)V");
+    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(J)V");
 
-    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT);
+    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, reinterpret_cast<jlong>(EGL_NO_CONTEXT));
     eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
-    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY);
+    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, reinterpret_cast<jlong>(EGL_NO_DISPLAY));
     eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
-    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE);
+    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, reinterpret_cast<jlong>(EGL_NO_SURFACE));
     eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
 
 
@@ -106,7 +106,8 @@
                           "Object is set to null.");
     }
 
-    return (void*) (_env->CallIntMethod(obj, mid));
+    jlong handle = _env->CallLongMethod(obj, mid);
+    return reinterpret_cast<void*>(handle);
 }
 
 static jobject
@@ -126,7 +127,7 @@
            return eglNoSurfaceObject;
     }
 
-    return _env->NewObject(cls, con, (jint)handle);
+    return _env->NewObject(cls, con, reinterpret_cast<jlong>(handle));
 }
 
 // --------------------------------------------------------------------------
@@ -142,14 +143,26 @@
 /* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
 static jobject
 android_eglGetDisplay
-  (JNIEnv *_env, jobject _this, jint display_id) {
+  (JNIEnv *_env, jobject _this, jlong display_id) {
     EGLDisplay _returnValue = (EGLDisplay) 0;
     _returnValue = eglGetDisplay(
-        (EGLNativeDisplayType)display_id
+        reinterpret_cast<EGLNativeDisplayType>(display_id)
     );
     return toEGLHandle(_env, egldisplayClass, egldisplayConstructor, _returnValue);
 }
 
+/* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
+static jobject
+android_eglGetDisplayInt
+  (JNIEnv *_env, jobject _this, jint display_id) {
+
+    if ((EGLNativeDisplayType)display_id != EGL_DEFAULT_DISPLAY) {
+        jniThrowException(_env, "java/lang/UnsupportedOperationException", "eglGetDisplay");
+        return 0;
+    }
+    return android_eglGetDisplay(_env, _this, display_id);
+}
+
 /* EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor ) */
 static jboolean
 android_eglInitialize
@@ -852,7 +865,7 @@
 /* EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */
 static jobject
 android_eglCreatePbufferFromClientBuffer
-  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jint buffer, jobject config, jintArray attrib_list_ref, jint offset) {
+  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jlong buffer, jobject config, jintArray attrib_list_ref, jint offset) {
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
@@ -897,7 +910,7 @@
     _returnValue = eglCreatePbufferFromClientBuffer(
         (EGLDisplay)dpy_native,
         (EGLenum)buftype,
-        (EGLClientBuffer)buffer,
+        reinterpret_cast<EGLClientBuffer>(buffer),
         (EGLConfig)config_native,
         (EGLint *)attrib_list
     );
@@ -913,6 +926,16 @@
     return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
 }
 
+static jobject
+android_eglCreatePbufferFromClientBufferInt
+  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jint buffer, jobject config, jintArray attrib_list_ref, jint offset) {
+    if(sizeof(void*) != sizeof(uint32_t)) {
+        jniThrowException(_env, "java/lang/UnsupportedOperationException", "eglCreatePbufferFromClientBuffer");
+        return 0;
+    }
+    return android_eglCreatePbufferFromClientBuffer(_env, _this, dpy, buftype, buffer, config, attrib_list_ref, offset);
+}
+
 /* EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) */
 static jboolean
 android_eglSurfaceAttrib
@@ -1207,7 +1230,8 @@
 static JNINativeMethod methods[] = {
 {"_nativeClassInit", "()V", (void*)nativeClassInit },
 {"eglGetError", "()I", (void *) android_eglGetError },
-{"eglGetDisplay", "(I)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplay },
+{"eglGetDisplay", "(I)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplayInt },
+{"eglGetDisplay", "(J)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplay },
 {"eglInitialize", "(Landroid/opengl/EGLDisplay;[II[II)Z", (void *) android_eglInitialize },
 {"eglTerminate", "(Landroid/opengl/EGLDisplay;)Z", (void *) android_eglTerminate },
 {"eglQueryString", "(Landroid/opengl/EGLDisplay;I)Ljava/lang/String;", (void *) android_eglQueryString__Landroind_opengl_EGLDisplay_2I },
@@ -1224,7 +1248,8 @@
 {"eglQueryAPI", "()I", (void *) android_eglQueryAPI },
 {"eglWaitClient", "()Z", (void *) android_eglWaitClient },
 {"eglReleaseThread", "()Z", (void *) android_eglReleaseThread },
-{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IILandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBuffer },
+{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IILandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBufferInt },
+{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IJLandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBuffer },
 {"eglSurfaceAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;II)Z", (void *) android_eglSurfaceAttrib },
 {"eglBindTexImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglBindTexImage },
 {"eglReleaseTexImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglReleaseTexImage },
diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp
index 5179ddc..15899f5 100644
--- a/core/jni/android_opengl_EGLExt.cpp
+++ b/core/jni/android_opengl_EGLExt.cpp
@@ -70,22 +70,22 @@
     jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
     eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
 
-    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I");
-    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I");
-    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I");
-    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I");
+    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J");
+    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getNativeHandle", "()J");
+    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J");
+    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getNativeHandle", "()J");
 
 
-    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(I)V");
-    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(I)V");
-    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(I)V");
-    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(I)V");
+    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(J)V");
+    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(J)V");
+    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(J)V");
+    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(J)V");
 
-    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT);
+    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, reinterpret_cast<jlong>(EGL_NO_CONTEXT));
     eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
-    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY);
+    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, reinterpret_cast<jlong>(EGL_NO_DISPLAY));
     eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
-    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE);
+    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, reinterpret_cast<jlong>(EGL_NO_SURFACE));
     eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
 
 
@@ -107,7 +107,7 @@
                           "Object is set to null.");
     }
 
-    return (void*) (_env->CallIntMethod(obj, mid));
+    return reinterpret_cast<void*>(_env->CallLongMethod(obj, mid));
 }
 
 static jobject
@@ -127,7 +127,7 @@
            return eglNoSurfaceObject;
     }
 
-    return _env->NewObject(cls, con, (jint)handle);
+    return _env->NewObject(cls, con, reinterpret_cast<jlong>(handle));
 }
 
 // --------------------------------------------------------------------------
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index cc34e99..21e19e1 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 9284384..bc83234 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index 871e84d..a45f269 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -578,7 +578,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -679,7 +679,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2302,7 +2302,7 @@
     glNormalPointer(
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -2529,7 +2529,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -2937,7 +2937,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index 3e038ad..05728ef 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index db03b70..d3e5014 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -1180,7 +1180,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1804,7 +1804,7 @@
         (GLsizei *)length,
         (GLint *)size,
         (GLenum *)type,
-        (char *)name
+        reinterpret_cast<char *>(name)
     );
     if (_typeArray) {
         releasePointer(_env, _typeArray, type, JNI_TRUE);
@@ -2132,7 +2132,7 @@
         (GLsizei *)length,
         (GLint *)size,
         (GLenum *)type,
-        (char *)name
+        reinterpret_cast<char *>(name)
     );
     if (_typeArray) {
         releasePointer(_env, _typeArray, type, JNI_TRUE);
@@ -3212,7 +3212,7 @@
         (GLuint)shader,
         (GLsizei)bufsize,
         (GLsizei *)length,
-        (char *)source
+        reinterpret_cast<char *>(source)
     );
     if (_array) {
         releasePointer(_env, _array, length, JNI_TRUE);
@@ -5985,7 +5985,7 @@
         (GLenum)type,
         (GLboolean)normalized,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 4c62a75..8821352 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -111,7 +111,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void*>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -370,7 +370,7 @@
         (GLuint)end,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -419,7 +419,7 @@
         (GLint)border,
         (GLenum)format,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -470,7 +470,7 @@
         (GLsizei)depth,
         (GLenum)format,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -534,7 +534,7 @@
         (GLsizei)depth,
         (GLint)border,
         (GLsizei)imageSize,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -585,7 +585,7 @@
         (GLsizei)depth,
         (GLenum)format,
         (GLsizei)imageSize,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -2134,7 +2134,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 480d0ac..c5ab284 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -61,54 +61,21 @@
 
 class ScreenshotPixelRef : public SkPixelRef {
 public:
-    ScreenshotPixelRef(SkColorTable* ctable) {
-        fCTable = ctable;
-        SkSafeRef(ctable);
+    ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) :
+      SkPixelRef(info),
+      mScreenshot(screenshot) {
         setImmutable();
     }
 
     virtual ~ScreenshotPixelRef() {
-        SkSafeUnref(fCTable);
-    }
-
-    status_t update(const sp<IBinder>& display, int width, int height,
-            int minLayer, int maxLayer, bool allLayers,
-            bool useIdentityTransform) {
-        status_t res = (width > 0 && height > 0)
-                ? (allLayers
-                        ? mScreenshot.update(display, width, height,
-                                useIdentityTransform)
-                        : mScreenshot.update(display, width, height,
-                                minLayer, maxLayer, useIdentityTransform))
-                : mScreenshot.update(display, useIdentityTransform);
-        if (res != NO_ERROR) {
-            return res;
-        }
-
-        return NO_ERROR;
-    }
-
-    uint32_t getWidth() const {
-        return mScreenshot.getWidth();
-    }
-
-    uint32_t getHeight() const {
-        return mScreenshot.getHeight();
-    }
-
-    uint32_t getStride() const {
-        return mScreenshot.getStride();
-    }
-
-    uint32_t getFormat() const {
-        return mScreenshot.getFormat();
+        delete mScreenshot;
     }
 
 protected:
     // overrides from SkPixelRef
     virtual void* onLockPixels(SkColorTable** ct) {
-        *ct = fCTable;
-        return (void*)mScreenshot.getPixels();
+        *ct = NULL;
+        return (void*)mScreenshot->getPixels();
     }
 
     virtual void onUnlockPixels() {
@@ -116,8 +83,7 @@
 
     SK_DECLARE_UNFLATTENABLE_OBJECT()
 private:
-    ScreenshotClient mScreenshot;
-    SkColorTable*    fCTable;
+    ScreenshotClient* mScreenshot;
 
     typedef SkPixelRef INHERITED;
 };
@@ -150,20 +116,6 @@
     ctrl->decStrong((void *)nativeCreate);
 }
 
-static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
-    /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
-        we can map to SkBitmap::kARGB_8888_Config, and optionally call
-        bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap
-        (as an accelerator)
-    */
-    switch (format) {
-    case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
-    case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
-    case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
-    default:                        return SkBitmap::kNo_Config;
-    }
-}
-
 static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
         jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
         bool useIdentityTransform) {
@@ -172,26 +124,57 @@
         return NULL;
     }
 
-    ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
-    if (pixels->update(displayToken, width, height,
-            minLayer, maxLayer, allLayers, useIdentityTransform) != NO_ERROR) {
-        delete pixels;
+    ScreenshotClient* screenshot = new ScreenshotClient();
+    status_t res;
+    if (width > 0 && height > 0) {
+        if (allLayers) {
+            res = screenshot->update(displayToken, width, height, useIdentityTransform);
+        } else {
+            res = screenshot->update(displayToken, width, height, minLayer, maxLayer,
+                    useIdentityTransform);
+        }
+    } else {
+        res = screenshot->update(displayToken, useIdentityTransform);
+    }
+    if (res != NO_ERROR) {
+        delete screenshot;
         return NULL;
     }
 
-    uint32_t w = pixels->getWidth();
-    uint32_t h = pixels->getHeight();
-    uint32_t s = pixels->getStride();
-    uint32_t f = pixels->getFormat();
-    ssize_t bpr = s * android::bytesPerPixel(f);
+    SkImageInfo screenshotInfo;
+    screenshotInfo.fWidth = screenshot->getWidth();
+    screenshotInfo.fHeight = screenshot->getHeight();
 
-    SkBitmap* bitmap = new SkBitmap();
-    bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
-    if (f == PIXEL_FORMAT_RGBX_8888) {
-        bitmap->setAlphaType(kOpaque_SkAlphaType);
+    switch (screenshot->getFormat()) {
+        case PIXEL_FORMAT_RGBX_8888: {
+            screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+            screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+            break;
+        }
+        case PIXEL_FORMAT_RGBA_8888: {
+            screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+            screenshotInfo.fAlphaType = kPremul_SkAlphaType;
+            break;
+        }
+        case PIXEL_FORMAT_RGB_565: {
+            screenshotInfo.fColorType = kRGB_565_SkColorType;
+            screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+            break;
+        }
+        default: {
+            delete screenshot;
+            return NULL;
+        }
     }
 
-    if (w > 0 && h > 0) {
+    // takes ownership of ScreenshotClient
+    ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot);
+    const ssize_t rowBytes =
+            screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
+
+    SkBitmap* bitmap = new SkBitmap();
+    bitmap->setConfig(screenshotInfo, (size_t)rowBytes);
+    if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
         bitmap->setPixelRef(pixels)->unref();
         bitmap->lockPixels();
     } else {
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index b3b0049..7975987 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -129,7 +129,7 @@
             getBasePointerID, buffer);
     if (pointer != 0L) {
         *array = NULL;
-        return (void *) (jint) pointer;
+        return reinterpret_cast<void *>(pointer);
     }
 
     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
@@ -4359,7 +4359,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -4460,7 +4460,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6099,7 +6099,7 @@
     glNormalPointer(
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -6326,7 +6326,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -6756,7 +6756,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -7196,7 +7196,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
@@ -7232,7 +7232,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (GLvoid *)offset
+        reinterpret_cast<GLvoid *>(offset)
     );
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 30e6161..55e21de 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1071,7 +1071,7 @@
         android:permissionGroupFlags="personalInfo"
         android:priority="370" />
 
-    <!-- Allows an application to monitor, modify, or abort outgoing
+    <!-- Allows an application to modify or abort outgoing
          calls. -->
     <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
         android:permissionGroup="android.permission-group.PHONE_CALLS"
diff --git a/core/res/res/color/primary_text_disable_only_quantum_dark.xml b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
index 2a6c33c..60a91f2 100644
--- a/core/res/res/color/primary_text_disable_only_quantum_dark.xml
+++ b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="@android:color/bright_foreground_dark_disabled"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_quantum_dark"/>
+    <item android:color="@android:color/bright_foreground_quantum_dark"/>
 </selector>
diff --git a/core/res/res/color/primary_text_disable_only_quantum_light.xml b/core/res/res/color/primary_text_disable_only_quantum_light.xml
index ff83f6a..ced9051 100644
--- a/core/res/res/color/primary_text_disable_only_quantum_light.xml
+++ b/core/res/res/color/primary_text_disable_only_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled"/>
-    <item android:color="@android:color/bright_foreground_light"/>
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_quantum_light"/>
+    <item android:color="@android:color/bright_foreground_quantum_light"/>
 </selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_light.xml b/core/res/res/color/primary_text_nodisable_quantum_light.xml
deleted file mode 100644
index fde143f..0000000
--- a/core/res/res/color/primary_text_nodisable_quantum_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_light"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_light"/>
-    <item android:color="@android:color/bright_foreground_light"/>
-</selector>
diff --git a/core/res/res/color/primary_text_quantum_dark.xml b/core/res/res/color/primary_text_quantum_dark.xml
deleted file mode 100644
index 65f49ae..0000000
--- a/core/res/res/color/primary_text_quantum_dark.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="@android:color/bright_foreground_disabled_holo_dark"/>
-    <item android:state_window_focused="false" android:color="@android:color/bright_foreground_holo_dark"/>
-    <item android:state_pressed="true" android:color="@android:color/bright_foreground_holo_dark"/>
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_holo_dark"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_dark"/>
-    <item android:color="@android:color/bright_foreground_holo_dark"/>
-</selector>
diff --git a/core/res/res/color/primary_text_quantum_light.xml b/core/res/res/color/primary_text_quantum_light.xml
deleted file mode 100644
index 372745d..0000000
--- a/core/res/res/color/primary_text_quantum_light.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="@android:color/bright_foreground_disabled_holo_light"/>
-    <item android:state_window_focused="false" android:color="@android:color/bright_foreground_holo_light"/>
-    <item android:state_pressed="true" android:color="@android:color/bright_foreground_holo_light"/>
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_holo_light"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_light"/>
-    <item android:color="@android:color/bright_foreground_holo_light"/>
-</selector>
diff --git a/core/res/res/color/search_url_text_quantum_dark.xml b/core/res/res/color/search_url_text_quantum_dark.xml
index 62337bd..5263fd7 100644
--- a/core/res/res/color/search_url_text_quantum_dark.xml
+++ b/core/res/res/color/search_url_text_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/core/res/res/color/search_url_text_quantum_light.xml b/core/res/res/color/search_url_text_quantum_light.xml
index 62337bd..5263fd7 100644
--- a/core/res/res/color/search_url_text_quantum_light.xml
+++ b/core/res/res/color/search_url_text_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/core/res/res/color/secondary_text_nodisable_quantum_dark.xml b/core/res/res/color/secondary_text_nodisable_quantum_dark.xml
deleted file mode 100644
index 3ab25a0..0000000
--- a/core/res/res/color/secondary_text_nodisable_quantum_dark.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/dim_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/dim_foreground_dark"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_nodisable_quantum_light.xml b/core/res/res/color/secondary_text_nodisable_quantum_light.xml
deleted file mode 100644
index 3ab25a0..0000000
--- a/core/res/res/color/secondary_text_nodisable_quantum_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/dim_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/dim_foreground_dark"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_quantum_dark.xml b/core/res/res/color/secondary_text_quantum_dark.xml
deleted file mode 100644
index fb7a07a..0000000
--- a/core/res/res/color/secondary_text_quantum_dark.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
-    <item android:state_window_focused="false" android:color="@android:color/dim_foreground_holo_dark"/>
-    <item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
-    <item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
-    <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_dark"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_dark"/>
-    <item android:state_pressed="true" android:color="@android:color/dim_foreground_holo_dark"/>
-    <item android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
-    <item android:color="@android:color/dim_foreground_holo_dark"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_quantum_light.xml b/core/res/res/color/secondary_text_quantum_light.xml
deleted file mode 100644
index 744ace5..0000000
--- a/core/res/res/color/secondary_text_quantum_light.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
-    <item android:state_window_focused="false" android:color="@android:color/dim_foreground_holo_light"/>
-    <!-- Since there is only one selector (for both light and dark), the light's selected state shouldn't be inversed like the dark's. -->
-    <item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
-    <item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
-    <item android:state_pressed="true" android:color="@android:color/dim_foreground_holo_light"/>
-    <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_light"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_light"/>
-    <item android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
-    <item android:color="@android:color/dim_foreground_holo_light"/>
-</selector>
diff --git a/core/res/res/color/tertiary_text_quantum_light.xml b/core/res/res/color/tertiary_text_quantum_light.xml
deleted file mode 100644
index b23162a..0000000
--- a/core/res/res/color/tertiary_text_quantum_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="#808080"/>
-    <item android:state_window_focused="false" android:color="#808080"/>
-    <item android:state_pressed="true" android:color="#808080"/>
-    <item android:state_selected="true" android:color="#808080"/>
-    <item android:color="#808080"/>
-</selector>
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm.9.png
new file mode 100644
index 0000000..e89c9fe
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png
new file mode 100644
index 0000000..f220168
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png
new file mode 100644
index 0000000..2a17861
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png
new file mode 100644
index 0000000..61067ac
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png
new file mode 100644
index 0000000..7d29d18
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..fdbbbce
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png
new file mode 100644
index 0000000..0ec2ee6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..b46ee1c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png
new file mode 100644
index 0000000..8737156
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png
new file mode 100644
index 0000000..7488ff9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png
new file mode 100644
index 0000000..e78fff6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png
new file mode 100644
index 0000000..a3d09657
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png
new file mode 100644
index 0000000..55a73e7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png
new file mode 100644
index 0000000..be64a94
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png
new file mode 100644
index 0000000..ca15853
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png
new file mode 100644
index 0000000..1f9c734
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png
new file mode 100644
index 0000000..10e0756
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png
new file mode 100644
index 0000000..e3a7e9e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png
new file mode 100644
index 0000000..f9cf16c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png
new file mode 100644
index 0000000..7c3a58b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png
new file mode 100644
index 0000000..2200642
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png
new file mode 100644
index 0000000..d35b337
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png
new file mode 100644
index 0000000..ff1759b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png
new file mode 100644
index 0000000..28c0ae0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png
new file mode 100644
index 0000000..cb295a3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png
new file mode 100644
index 0000000..6430d45
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png
new file mode 100644
index 0000000..66f7d16
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..0fafd1a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..491fab9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..2d4eb3f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png
new file mode 100644
index 0000000..74a259b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png
new file mode 100644
index 0000000..c1c0622
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..0319bd8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png
new file mode 100644
index 0000000..c11b0ae
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..b46ee1c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png
new file mode 100644
index 0000000..cde797e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..6a82af5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png
new file mode 100644
index 0000000..b8c78b5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png
new file mode 100644
index 0000000..9e234af
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png
new file mode 100644
index 0000000..b371eab
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png
new file mode 100644
index 0000000..74a259b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
new file mode 100644
index 0000000..0a14025
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
new file mode 100644
index 0000000..20e291a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png
new file mode 100644
index 0000000..432c385
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png
new file mode 100644
index 0000000..a22f352
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png
new file mode 100644
index 0000000..b0504e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ab_transparent_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ab_transparent_quantum_dark.xml
index 59d9fcf..9ac2fc0 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ab_transparent_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ab_transparent_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ab_transparent_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ab_transparent_quantum_light.xml
index 59d9fcf..bc49848 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ab_transparent_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ab_transparent_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/activated_background_quantum_dark.xml
similarity index 72%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/activated_background_quantum_dark.xml
index 59d9fcf..a9e3fea 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/activated_background_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_activated="true" android:drawable="@color/control_activated_foreground_quantum_dark" />
+    <item android:drawable="@color/transparent" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/activated_background_quantum_light.xml
similarity index 72%
rename from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
rename to core/res/res/drawable/activated_background_quantum_light.xml
index 59d9fcf..5d10ea2 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/activated_background_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_activated="true" android:drawable="@color/control_activated_foreground_quantum_light" />
+    <item android:drawable="@color/transparent" />
 </selector>
diff --git a/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml b/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
index 7d64abc..ab66501 100644
--- a/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
+++ b/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml b/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
index 3fc3483..fb940a9 100644
--- a/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
+++ b/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/btn_borderless_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/btn_borderless_quantum_dark.xml
index 59d9fcf..e1bff4f 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/btn_borderless_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,10 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@color/transparent" />
+    <item>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/btn_default_pressed_quantum_dark" />
+    </item>
+</reveal>
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/btn_borderless_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/btn_borderless_quantum_light.xml
index 59d9fcf..e7a95b1 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/btn_borderless_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,10 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@color/transparent" />
+    <item>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/btn_default_pressed_quantum_light" />
+    </item>
+</reveal>
diff --git a/core/res/res/drawable/btn_check_quantum_dark.xml b/core/res/res/drawable/btn_check_quantum_dark.xml
new file mode 100644
index 0000000..a35bec4
--- /dev/null
+++ b/core/res/res/drawable/btn_check_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_check_quantum_light.xml b/core/res/res/drawable/btn_check_quantum_light.xml
new file mode 100644
index 0000000..8588fce
--- /dev/null
+++ b/core/res/res/drawable/btn_check_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_color_quantum_dark.xml b/core/res/res/drawable/btn_color_quantum_dark.xml
new file mode 100644
index 0000000..5e44a78
--- /dev/null
+++ b/core/res/res/drawable/btn_color_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <selector>
+            <item android:state_enabled="false">
+                <nine-patch android:src="@drawable/btn_qntm_alpha"
+                    android:tint="@color/btn_default_normal_quantum_light" />
+            </item>
+            <item>
+                <nine-patch android:src="@drawable/btn_qntm_alpha"
+                    android:tint="@color/theme_color_500" />
+            </item>
+        </selector>
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/theme_color_300" />
+    </item>
+</reveal>
diff --git a/core/res/res/drawable/btn_color_quantum_light.xml b/core/res/res/drawable/btn_color_quantum_light.xml
new file mode 100644
index 0000000..d6be958
--- /dev/null
+++ b/core/res/res/drawable/btn_color_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <selector>
+            <item android:state_enabled="false">
+                <nine-patch android:src="@drawable/btn_qntm_alpha"
+                    android:tint="@color/btn_default_normal_quantum_dark" />
+            </item>
+            <item>
+                <nine-patch android:src="@drawable/btn_qntm_alpha"
+                    android:tint="@color/theme_color_500" />
+            </item>
+        </selector>
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/theme_color_700" />
+    </item>
+</reveal>
diff --git a/core/res/res/drawable/btn_default_quantum_dark.xml b/core/res/res/drawable/btn_default_quantum_dark.xml
index 84b1090..7f0cca8 100644
--- a/core/res/res/drawable/btn_default_quantum_dark.xml
+++ b/core/res/res/drawable/btn_default_quantum_dark.xml
@@ -16,20 +16,11 @@
 
 <reveal xmlns:android="http://schemas.android.com/apk/res/android">
     <item>
-        <selector>
-            <item android:state_window_focused="false" android:state_enabled="true"
-                android:drawable="@drawable/btn_default_normal_holo_dark" />
-            <item android:state_window_focused="false" android:state_enabled="false"
-                android:drawable="@drawable/btn_default_disabled_holo_dark" />
-            <item android:state_focused="true" android:state_enabled="true"
-                android:drawable="@drawable/btn_default_focused_holo_dark" />
-            <item android:state_enabled="true"
-                android:drawable="@drawable/btn_default_normal_holo_dark" />
-            <item android:state_focused="true"
-                android:drawable="@drawable/btn_default_disabled_focused_holo_dark" />
-            <item
-                android:drawable="@drawable/btn_default_disabled_holo_dark" />
-        </selector>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/btn_default_normal_quantum_dark" />
     </item>
-    <item android:drawable="@drawable/btn_default_pressed_holo_dark" />
+    <item>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/btn_default_pressed_quantum_dark" />
+    </item>
 </reveal>
diff --git a/core/res/res/drawable/btn_default_quantum_light.xml b/core/res/res/drawable/btn_default_quantum_light.xml
index b559198..e391a80 100644
--- a/core/res/res/drawable/btn_default_quantum_light.xml
+++ b/core/res/res/drawable/btn_default_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -16,20 +16,11 @@
 
 <reveal xmlns:android="http://schemas.android.com/apk/res/android">
     <item>
-        <selector>
-            <item android:state_window_focused="false" android:state_enabled="true"
-                android:drawable="@drawable/btn_default_normal_holo_light" />
-            <item android:state_window_focused="false" android:state_enabled="false"
-                android:drawable="@drawable/btn_default_disabled_holo_light" />
-            <item android:state_focused="true" android:state_enabled="true"
-                android:drawable="@drawable/btn_default_focused_holo_light" />
-            <item android:state_enabled="true"
-                android:drawable="@drawable/btn_default_normal_holo_light" />
-            <item android:state_focused="true"
-                android:drawable="@drawable/btn_default_disabled_focused_holo_light" />
-            <item
-                android:drawable="@drawable/btn_default_disabled_holo_light" />
-        </selector>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/btn_default_normal_quantum_light" />
     </item>
-    <item android:drawable="@drawable/btn_default_pressed_holo_light" />
+    <item>
+        <nine-patch android:src="@drawable/btn_qntm_alpha"
+            android:tint="@color/btn_default_pressed_quantum_light" />
+    </item>
 </reveal>
diff --git a/core/res/res/drawable/btn_radio_quantum_dark.xml b/core/res/res/drawable/btn_radio_quantum_dark.xml
new file mode 100644
index 0000000..54f4f9a
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_radio_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_off_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_radio_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_radio_quantum_light.xml b/core/res/res/drawable/btn_radio_quantum_light.xml
new file mode 100644
index 0000000..c1ace70
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_radio_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_off_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_radio_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_star_quantum_dark.xml b/core/res/res/drawable/btn_star_quantum_dark.xml
new file mode 100644
index 0000000..7b26a3c
--- /dev/null
+++ b/core/res/res/drawable/btn_star_quantum_dark.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_star_quantum_light.xml b/core/res/res/drawable/btn_star_quantum_light.xml
new file mode 100644
index 0000000..df2cc91
--- /dev/null
+++ b/core/res/res/drawable/btn_star_quantum_light.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/edit_text_quantum_dark.xml b/core/res/res/drawable/edit_text_quantum_dark.xml
new file mode 100644
index 0000000..ea3fc52
--- /dev/null
+++ b/core/res/res/drawable/edit_text_quantum_dark.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item android:state_window_focused="false" android:state_enabled="false">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true" android:state_activated="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/edit_text_quantum_light.xml b/core/res/res/drawable/edit_text_quantum_light.xml
new file mode 100644
index 0000000..dd7fe53
--- /dev/null
+++ b/core/res/res/drawable/edit_text_quantum_light.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item android:state_window_focused="false" android:state_enabled="false">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true" android:state_activated="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/color/tertiary_text_quantum_dark.xml b/core/res/res/drawable/expander_group_quantum_dark.xml
similarity index 62%
rename from core/res/res/color/tertiary_text_quantum_dark.xml
rename to core/res/res/drawable/expander_group_quantum_dark.xml
index cb39565..7250e01 100644
--- a/core/res/res/color/tertiary_text_quantum_dark.xml
+++ b/core/res/res/drawable/expander_group_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,9 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="#808080"/>
-    <item android:state_window_focused="false" android:color="#808080"/>
-    <item android:state_pressed="true" android:color="#808080"/>
-    <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_light"/>
-    <item android:color="#808080"/>
+    <item android:state_expanded="true">
+        <nine-patch android:src="@drawable/expander_close_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/expander_open_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
 </selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/expander_group_quantum_light.xml
similarity index 61%
copy from core/res/res/color/primary_text_nodisable_quantum_dark.xml
copy to core/res/res/drawable/expander_group_quantum_light.xml
index 1044428..62af983 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/expander_group_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_expanded="true">
+        <nine-patch android:src="@drawable/expander_close_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/expander_open_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
 </selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml
similarity index 62%
rename from core/res/res/color/primary_text_nodisable_quantum_dark.xml
rename to core/res/res/drawable/fastscroll_thumb_quantum_dark.xml
index 1044428..53c7fdd 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
 </selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/fastscroll_thumb_quantum_light.xml
similarity index 61%
copy from core/res/res/color/primary_text_nodisable_quantum_dark.xml
copy to core/res/res/drawable/fastscroll_thumb_quantum_light.xml
index 1044428..3bc87e9 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/fastscroll_thumb_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
 </selector>
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/fastscroll_track_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/fastscroll_track_quantum_dark.xml
index 59d9fcf..0ae57d2 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/fastscroll_track_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/fastscroll_track_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/fastscroll_track_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/fastscroll_track_quantum_light.xml
index 59d9fcf..627c079 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/fastscroll_track_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/fastscroll_track_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_ab_back_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_ab_back_quantum_dark.xml
index 59d9fcf..628d53e 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_ab_back_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_ab_back_qntm_am_alpha"
+    android:autoMirrored="true"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_ab_back_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_ab_back_quantum_light.xml
index 59d9fcf..01f5362 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_ab_back_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_ab_back_qntm_am_alpha"
+    android:autoMirrored="true"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_cab_done_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_cab_done_quantum_dark.xml
index 59d9fcf..472996e 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_cab_done_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_cab_done_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_cab_done_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_cab_done_quantum_light.xml
index 59d9fcf..d70a3f1 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_cab_done_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_cab_done_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
index 59d9fcf..8b8cb0c 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_dialog_alert_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_dialog_alert_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_dialog_alert_quantum_light.xml
index 59d9fcf..8b8cb0c 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_dialog_alert_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_dialog_alert_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_find_next_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_find_next_quantum_dark.xml
index 59d9fcf..929bea3 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_find_next_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_find_next_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_find_next_quantum_light.xml
index 59d9fcf..9c20327 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_find_next_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_find_previous_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_find_previous_quantum_dark.xml
index 59d9fcf..e944223 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_find_previous_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_previous_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_find_previous_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_find_previous_quantum_light.xml
index 59d9fcf..b037094 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_find_previous_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_previous_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/anim/notification_dnd_off.xml b/core/res/res/drawable/ic_menu_copy_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/anim/notification_dnd_off.xml
copy to core/res/res/drawable/ic_menu_copy_quantum_dark.xml
index 4e88855..285b752 100644
--- a/packages/SystemUI/res/anim/notification_dnd_off.xml
+++ b/core/res/res/drawable/ic_menu_copy_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,10 +14,7 @@
      limitations under the License.
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromXDelta="100%p" android:toXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_copy_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark"
+    android:autoMirrored="true" />
diff --git a/packages/SystemUI/res/anim/notification_dnd_off.xml b/core/res/res/drawable/ic_menu_copy_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/anim/notification_dnd_off.xml
copy to core/res/res/drawable/ic_menu_copy_quantum_light.xml
index 4e88855..a40b219 100644
--- a/packages/SystemUI/res/anim/notification_dnd_off.xml
+++ b/core/res/res/drawable/ic_menu_copy_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,10 +14,7 @@
      limitations under the License.
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromXDelta="100%p" android:toXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_copy_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light"
+    android:autoMirrored="true" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_cut_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_cut_quantum_dark.xml
index 59d9fcf..563400b 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_cut_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_cut_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_cut_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_cut_quantum_light.xml
index 59d9fcf..36c9442 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_cut_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_cut_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_find_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_find_quantum_dark.xml
index 59d9fcf..8803463 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_find_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_find_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_find_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_find_quantum_light.xml
index 59d9fcf..9b3bd73 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_find_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_find_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml
index 59d9fcf..9f39a68 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
index 59d9fcf..e15eaec 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/anim/notification_dnd_off.xml b/core/res/res/drawable/ic_menu_paste_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/anim/notification_dnd_off.xml
copy to core/res/res/drawable/ic_menu_paste_quantum_dark.xml
index 4e88855..7033404 100644
--- a/packages/SystemUI/res/anim/notification_dnd_off.xml
+++ b/core/res/res/drawable/ic_menu_paste_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,10 +14,7 @@
      limitations under the License.
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromXDelta="100%p" android:toXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_paste_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark"
+    android:autoMirrored="true" />
diff --git a/packages/SystemUI/res/anim/notification_dnd_off.xml b/core/res/res/drawable/ic_menu_paste_quantum_light.xml
similarity index 64%
rename from packages/SystemUI/res/anim/notification_dnd_off.xml
rename to core/res/res/drawable/ic_menu_paste_quantum_light.xml
index 4e88855..155ec34 100644
--- a/packages/SystemUI/res/anim/notification_dnd_off.xml
+++ b/core/res/res/drawable/ic_menu_paste_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,10 +14,7 @@
      limitations under the License.
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromXDelta="100%p" android:toXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_paste_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light"
+    android:autoMirrored="true" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_search_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_search_quantum_dark.xml
index 59d9fcf..1c6efcd 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_search_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_search_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_search_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_search_quantum_light.xml
index 59d9fcf..ba6efb6 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_search_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_search_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_selectall_quantum_dark.xml
index 59d9fcf..c1d3e69 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_selectall_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_selectall_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_selectall_quantum_light.xml
index 59d9fcf..4de8962 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_selectall_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_selectall_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_share_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_share_quantum_dark.xml
index 59d9fcf..a7c5afc 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_share_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_share_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/ic_menu_share_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/ic_menu_share_quantum_light.xml
index 59d9fcf..9257c25 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/ic_menu_share_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_share_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/item_background_borderless_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/item_background_borderless_quantum_dark.xml
index 59d9fcf..1caee4e 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/item_background_borderless_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,5 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/lighter_gray" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/item_background_borderless_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/item_background_borderless_quantum_light.xml
index 59d9fcf..ecf7dfb 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/item_background_borderless_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,5 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/darker_gray" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/list_divider_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/list_divider_quantum_dark.xml
index 59d9fcf..9d05b2f 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/list_divider_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/list_divider_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/list_divider_quantum_light.xml
index 59d9fcf..d312e2d 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/list_divider_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/list_section_divider_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/list_section_divider_quantum_dark.xml
index 59d9fcf..6344c7e 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/list_section_divider_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_section_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/list_section_divider_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/list_section_divider_quantum_light.xml
index 59d9fcf..98ede38 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/list_section_divider_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_section_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/list_selector_quantum_dark.xml b/core/res/res/drawable/list_selector_quantum_dark.xml
deleted file mode 100644
index fea55a8..0000000
--- a/core/res/res/drawable/list_selector_quantum_dark.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<reveal xmlns:android="http://schemas.android.com/apk/res/android">
-    <selector>
-        <item android:state_window_focused="false" android:drawable="@color/transparent" />
-        <item android:state_focused="true" android:state_enabled="false"
-            android:drawable="@drawable/list_selector_disabled_holo_dark" />
-        <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
-    </selector>
-    <selector>
-        <item android:state_window_focused="false" android:drawable="@color/transparent" />
-        <item android:state_focused="true" android:state_enabled="false"
-            android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" />
-        <item android:state_focused="true" android:state_pressed="true"
-            android:drawable="@drawable/list_selector_background_transition_holo_dark" />
-        <item android:state_focused="false" android:state_pressed="true"
-            android:drawable="@drawable/list_selector_background_transition_holo_dark" />
-    </selector>
-</reveal>
diff --git a/core/res/res/drawable/list_selector_quantum_light.xml b/core/res/res/drawable/list_selector_quantum_light.xml
deleted file mode 100644
index 1e32eac..0000000
--- a/core/res/res/drawable/list_selector_quantum_light.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<reveal xmlns:android="http://schemas.android.com/apk/res/android">
-    <selector>
-        <item android:state_window_focused="false" android:drawable="@color/transparent" />
-        <item android:state_focused="true" android:state_enabled="false"
-            android:drawable="@drawable/list_selector_disabled_holo_light" />
-        <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
-    </selector>
-    <selector>
-        <item android:state_window_focused="false" android:drawable="@color/transparent" />
-        <item android:state_focused="true" android:state_enabled="false"
-            android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" />
-        <item android:state_focused="true" android:state_pressed="true"
-            android:drawable="@drawable/list_selector_background_transition_holo_light" />
-        <item android:state_focused="false" android:state_pressed="true"
-            android:drawable="@drawable/list_selector_background_transition_holo_light" />
-    </selector>
-</reveal>
diff --git a/core/res/res/drawable/progress_horizontal_quantum_dark.xml b/core/res/res/drawable/progress_horizontal_quantum_dark.xml
new file mode 100644
index 0000000..fb4b67e
--- /dev/null
+++ b/core/res/res/drawable/progress_horizontal_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@id/background">
+        <nine-patch android:src="@drawable/progress_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item android:id="@id/secondaryProgress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_dark" />
+        </scale>
+    </item>
+    <item android:id="@id/progress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_primary_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_dark" />
+        </scale>
+    </item>
+</layer-list>
diff --git a/core/res/res/drawable/progress_horizontal_quantum_light.xml b/core/res/res/drawable/progress_horizontal_quantum_light.xml
new file mode 100644
index 0000000..1ceb2e2
--- /dev/null
+++ b/core/res/res/drawable/progress_horizontal_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@id/background">
+        <nine-patch android:src="@drawable/progress_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item android:id="@id/secondaryProgress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_light" />
+        </scale>
+    </item>
+    <item android:id="@id/progress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_primary_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_light" />
+        </scale>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/scrollbar_handle_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/scrollbar_handle_quantum_dark.xml
index 59d9fcf..2d4e37d 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/scrollbar_handle_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/scrollbar_handle_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/scrollbar_handle_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/scrollbar_handle_quantum_light.xml
index 59d9fcf..d4d4b8d 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/scrollbar_handle_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/scrollbar_handle_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml b/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml
new file mode 100644
index 0000000..521bcca
--- /dev/null
+++ b/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_control_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum_light.xml b/core/res/res/drawable/scrubber_control_selector_quantum_light.xml
new file mode 100644
index 0000000..8d009b7
--- /dev/null
+++ b/core/res/res/drawable/scrubber_control_selector_quantum_light.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_control_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml
similarity index 61%
copy from core/res/res/color/primary_text_nodisable_quantum_dark.xml
copy to core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml
index 1044428..fa0d631 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
 </selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
similarity index 61%
copy from core/res/res/color/primary_text_nodisable_quantum_dark.xml
copy to core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
index 1044428..053f542 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
 </selector>
diff --git a/core/res/res/drawable/spinner_background_quantum_dark.xml b/core/res/res/drawable/spinner_background_quantum_dark.xml
new file mode 100644
index 0000000..d1e7407
--- /dev/null
+++ b/core/res/res/drawable/spinner_background_quantum_dark.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/spinner_background_quantum_light.xml b/core/res/res/drawable/spinner_background_quantum_light.xml
new file mode 100644
index 0000000..b01628d
--- /dev/null
+++ b/core/res/res/drawable/spinner_background_quantum_light.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/switch_inner_quantum_dark.xml b/core/res/res/drawable/switch_inner_quantum_dark.xml
new file mode 100644
index 0000000..927a55e
--- /dev/null
+++ b/core/res/res/drawable/switch_inner_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/switch_inner_quantum_light.xml b/core/res/res/drawable/switch_inner_quantum_light.xml
new file mode 100644
index 0000000..b5aa47b
--- /dev/null
+++ b/core/res/res/drawable/switch_inner_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/switch_track_quantum_dark.xml
similarity index 62%
copy from core/res/res/color/primary_text_nodisable_quantum_dark.xml
copy to core/res/res/drawable/switch_track_quantum_dark.xml
index 1044428..c018bd2 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/switch_track_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
 </selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/drawable/switch_track_quantum_light.xml
similarity index 61%
copy from core/res/res/color/primary_text_nodisable_quantum_dark.xml
copy to core/res/res/drawable/switch_track_quantum_light.xml
index 1044428..ab87a57 100644
--- a/core/res/res/color/primary_text_nodisable_quantum_dark.xml
+++ b/core/res/res/drawable/switch_track_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,7 +15,12 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
-    <item android:color="@android:color/bright_foreground_dark"/>
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
 </selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum_dark.xml b/core/res/res/drawable/tab_indicator_quantum_dark.xml
new file mode 100644
index 0000000..9b57c33
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_quantum_dark.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_selected="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_selected="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum_light.xml b/core/res/res/drawable/tab_indicator_quantum_light.xml
new file mode 100644
index 0000000..371322a
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_quantum_light.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_selected="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_selected="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/text_cursor_quantum_dark.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/text_cursor_quantum_dark.xml
index 59d9fcf..bd0d66f 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/text_cursor_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/text_cursor_qntm_alpha"
+    android:tint="@color/control_activated_foreground_quantum_dark" />
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/core/res/res/drawable/text_cursor_quantum_light.xml
similarity index 64%
copy from packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
copy to core/res/res/drawable/text_cursor_quantum_light.xml
index 59d9fcf..0ec7f01 100644
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
+++ b/core/res/res/drawable/text_cursor_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
+<!-- Copyright (C) 2014 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"
-          android:drawable="@drawable/heads_up_notification_bg_pressed" />
-</selector>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/text_cursor_qntm_alpha"
+    android:tint="@color/control_activated_foreground_quantum_light" />
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index e495e53..d2fe9fa 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -34,6 +34,7 @@
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         style="?android:attr/actionBarStyle"
+        android:sharedElementName="android:action_bar"
         android:gravity="top">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index b1889a2..3265736 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -23,7 +23,8 @@
     android:id="@+id/action_bar_overlay_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:splitMotionEvents="false">
+    android:splitMotionEvents="false"
+    android:theme="?attr/actionBarTheme">
     <FrameLayout android:id="@android:id/content"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
@@ -33,6 +34,7 @@
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         style="?android:attr/actionBarStyle"
+        android:sharedElementName="android:action_bar"
         android:gravity="top">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
diff --git a/core/res/res/layout/screen_custom_title.xml b/core/res/res/layout/screen_custom_title.xml
index e3364d1..d02cc8b 100644
--- a/core/res/res/layout/screen_custom_title.xml
+++ b/core/res/res/layout/screen_custom_title.xml
@@ -31,6 +31,7 @@
     <FrameLayout android:id="@android:id/title_container" 
         android:layout_width="match_parent" 
         android:layout_height="?android:attr/windowTitleSize"
+        android:sharedElementName="android:title"
         style="?android:attr/windowTitleBackgroundStyle">
     </FrameLayout>
     <FrameLayout android:id="@android:id/content"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4f38a82..9156057 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -46,7 +46,7 @@
     <string name="badPin" msgid="9015277645546710014">"የተየበከው የድሮ ፒን ትክክል አይደለም።"</string>
     <string name="badPuk" msgid="5487257647081132201">"የተየብከው PUK ትክክል  አይደለም።"</string>
     <string name="mismatchPin" msgid="609379054496863419">"ያስገባሃቸው ፒኖች አይዛመዱም"</string>
-    <string name="invalidPin" msgid="3850018445187475377">"ከ4 እስከ 8 ቁጥሮች የያዘ PIN ተይብ"</string>
+    <string name="invalidPin" msgid="3850018445187475377">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን  ተይብ"</string>
     <string name="invalidPuk" msgid="8761456210898036513">"8 ወይም ከዛ በላይ የሆኑ ቁጥሮችንPUK ተይብ።"</string>
     <string name="needPuk" msgid="919668385956251611">"SIM ካርድዎ PUK-የተቆለፈ ነው።የPUK ኮዱን በመተየብ ይክፈቱት።"</string>
     <string name="needPuk2" msgid="4526033371987193070">" SIM ለመክፈት PUK2 ተይብ።"</string>
@@ -832,7 +832,7 @@
     <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"የይለፍ ቃል ለመተየብ ንካ"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ለመክፈት የይለፍ ቃል ተይብ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ለመክፈት ፒን ተይብ"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ PIN ኮድ።"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ ፒን  ኮድ።"</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"ለመክፈት፣ምናሌ ተጫን ከዛ 0"</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"የአደጋ ጊዜቁጥር"</string>
     <string name="lockscreen_carrier_default" msgid="8963839242565653192">"ከአገልግሎት መስጫ ክልል ውጪ"</string>
@@ -994,8 +994,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"ጥያቄ አስረክብ"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"የድምፅ ፍለጋ"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"በመንካት አስስ ይንቃ?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>  ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከጡባዊ ተኮው ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>  ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከስልኩ ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>  ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከጡባዊ ተኮው ጋር ለመግባባት ምን በጣትዎ ስር ወይም ምልክቶችን ማከናወን እንዳለብዎ ማብራሪያ ሊመለከቱ ወይም ሊሰሙ ይችላሉ።"</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>  ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከስልኩ ጋር ለመግባባት ምን በጣትዎ ስር ወይም ምልክቶችን ማከናወን እንዳለብዎ ማብራሪያ ሊመለከቱ ወይም ሊሰሙ ይችላሉ።"</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"ከ1 ወር በፊት"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ከ1 ወር በፊት"</string>
   <plurals name="num_seconds_ago">
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 50c7187..cde9bdf 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -683,8 +683,8 @@
     <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permet que l\'aplicació modifiqui les marques de sòcols per a l\'encaminament"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accedeix a les notificacions"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet que l\'aplicació recuperi, examini i esborri les notificacions, incloses les que han publicat altres aplicacions."</string>
-    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincula a un servei de processament de notificacions"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei de processament de notificacions. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincula a un servei oient de notificacions"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei oient de notificacions. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoca l\'aplicació de configuració proporcionada per l\'operador"</string>
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet que el titular invoqui l\'aplicació de configuració proporcionada per l\'operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"conèixer les observacions sobre les condicions de la xarxa"</string>
@@ -1346,7 +1346,7 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilitat"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Canvia el fons de pantalla"</string>
-    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Processador de notificacions"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Oient de notificacions"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ha activat VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toca per gestionar la xarxa."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 69ca648..010f812 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -563,8 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním smí bez upozornění přepínat sítě, zapínat a vypínat bezdrátový modul telefonu a podobně."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čtení stavu a identity telefonu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikaci získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor, a vzdálené číslo, ke kterému je hovor připojen."</string>
-    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čtení přesných stavů telefonů"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikaci používat přesné stavy telefonů. Toto oprávnění aplikaci umožňuje zjistit skutečný stav volání, zda je volání aktivní nebo na pozadí, zda volání selhalo, přesný stav datového připojení a zda datové připojení selhalo."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čtení přesného stavu telefonování"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikaci zjišťovat přesný stav telefonování a mobilních dat. Toto oprávnění aplikaci umožňuje zjistit skutečný stav volání, zda je volání aktivní nebo na pozadí, zda volání selhalo, přesný stav datového připojení a zda datové připojení selhalo."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"bránění přechodu tabletu do režimu spánku"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"bránění přechodu telefonu do režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikaci zabránit přechodu tabletu do režimu spánku."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6b12c26..545b317 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -563,7 +563,7 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, encender y apagar la radio del teléfono y tareas similares sin siquiera notificártelo."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"leer la identidad y el estado del dispositivo"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string>
-    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Leer estados precisos del teléfono"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"leer estados precisos del teléfono"</string>
     <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que la aplicación acceda a los estados precisos del teléfono y determine el estado real de la llamada, si hay una llamada activa o en segundo plano, si se produjeron fallos en la llamada, el estado preciso de la conexión de datos y si hubo fallos relacionados con la conexión de datos."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evitar que el tablet entre en estado de inactividad"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar que el dispositivo entre en estado de inactividad"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1fed273..1f2a6cc 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -423,7 +423,7 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"‏اجازه می‎دهد برنامه از هر رمزگشای رسانه نصب شده‌ای استفاده کند تا برای پخش رمزگشایی شود."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"مدیریت اطلاعات کاربری مورد اعتماد"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏به برنامه امکان می‌دهد گواهینامه‌های CA را به عنوان اطلاعات کاربری مورد اعتماد نصب یا حذف نصب کند."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"اجرای برنامه در هنگام بی‌حرکت بودن دستگاه"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"اجرای برنامه در هنگام بدون فعالیت بودن دستگاه"</string>
     <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏این مجوز به سیستم Android امکان می‌دهد تا وقتی دستگاه استفاده نمی‌شود برنامه را در پس‌زمینه اجرا کند."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ به‌عنوان مثال، فایل‌های /dev. این امر به‌صورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"خواندن وضعیت تلفن و شناسه"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"به برنامه اجازه می‌دهد به ویژگی‌های تلفن دستگاه شما دسترسی پیدا کند. این مجوز به برنامه اجازه می‌دهد شماره تلفن و شناسه‌های دستگاه، فعال بودن یک تماس و شماره راه دوری که با یک تماس متصل شده است را مشخص کند."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"خواندن وضعیت‌های دقیق تلفن"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"به برنامه امکان می‌دهد به وضعیت‌های دقیق تلفن دسترسی داشته باشد. این مجوز به برنامه امکان می‌دهد وضعیت واقعی تماس اینکه آیا تماس فعال است یا در پس‌زمینه قرار دارد، تماس‌های ناموفق، وضعیت دقیق اتصال داده و اتصال‌های ناموفق داده را تعیین کند."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"به برنامه امکان می‌دهد به وضعیت‌های دقیق تلفن دسترسی داشته باشد. این مجوز به برنامه امکان می‌دهد وضعیت واقعی تماس، اینکه آیا تماس فعال است یا در پس‌زمینه قرار دارد، تماس‌های ناموفق، وضعیت دقیق اتصال داده و اتصال‌های ناموفق داده را تعیین کند."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ممانعت از به خواب رفتن رایانهٔ لوحی"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ممانعت از به خواب رفتن تلفن"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"‏به برنامه اجازه می‎دهد تا از غیرفعال شدن رایانهٔ لوحی جلوگیری کند."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 4504bad..b048bbc 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -635,7 +635,7 @@
     <string name="permlab_bluetooth" msgid="6127769336339276828">"uparivanje s Bluetooth uređajima"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na tabletnom računalu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na telefonu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
-    <string name="permlab_nfc" msgid="4423351274757876953">"upravljaj beskontaktnom (NFC) komunikacijom"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja zaslona"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji omogućuje onemogućavanje zaključavanja tipkovnice i svih pripadajućih sigurnosnih zaporki. Na primjer, telefon onemogućuje zaključavanje tipkovnice kod primanja dolaznog telefonskog poziva, nakon kojeg se zaključavanje tipkovnice ponovo omogućuje."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 92ab180..1547900 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefonállapot és azonosító olvasása"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az eszköz telefonálási funkcióihoz. Az engedéllyel rendelkező alkalmazás meghatározhatja a telefonszámot és eszközazonosítókat, hogy egy hívás aktív-e, valamint híváskor a másik fél telefonszámát."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"pontos telefonállapot megállapítása"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Engedélyezi, hogy az alkalmazás hozzáférjen a pontos telefonállapothoz. Az ilyen engedéllyel rendelkező alkalmazás képes meghatározni a valós hívási állapotot: hogy egy hívás aktív-e vagy a háttérben van, a hívás meghiúsult-e, illetve a pontos adatkapcsoltot és az adatkapcsolati műveletek meghiúsulását."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Engedélyezi, hogy az alkalmazás hozzáférjen a pontos telefonállapothoz. Az ilyen engedéllyel rendelkező alkalmazás képes meghatározni a valós hívási állapotot, azt, hogy egy hívás aktív-e vagy a háttérben van, a hívás meghiúsult-e, illetve képes meghatározni az adatkapcsolat pontos állapotát és az adatkapcsolati műveletek meghiúsulását."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"táblagép alvás üzemmódjának megakadályozása"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefon alvó üzemmódjának megakadályozása"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a táblagép alvó üzemmódra váltson."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e08dd93..a8cb3d2 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"skaityti telefono būseną ir tapatybę"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Leidžiama programai pasiekti telefono funkcijas įrenginyje. Šis leidimas suteikia teisę programai nustatyti telefono numerį ir įrenginio ID, tai, ar skambutis aktyvus, ir skambučiu prijungtą nuotolinį numerį."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"skaityti tikslias telefono būsenas"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Programai leidžiama pasiekti tikslias telefono būsenas. Šiuo leidimu programai leidžiama nustatyti tikrą skambučio būseną, ar skambutis yra aktyvus, ar vyksta fone, ar paskambinti nepavyksta, tikslią duomenų ryšio būseną ir ar nepavyksta užmegzto duomenų ryšio."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Programai leidžiama pasiekti tikslias telefono būsenas. Šiuo leidimu programai leidžiama nustatyti tikrą skambučio būseną, ar skambutis yra aktyvus, ar vyksta fone, ar paskambinti nepavyksta, tikslią duomenų ryšio būseną ir ar nepavyksta užmegzti duomenų ryšio."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"neleisti planšetiniam kompiuteriui užmigti"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"neleisti telefonui snausti"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Leidžiama programai neleisti planšetiniam kompiuteriui užmigti."</string>
diff --git a/core/res/res/values-mcc440-mnc20/config.xml b/core/res/res/values-mcc440-mnc20/config.xml
index ba709fa..62001d9 100644
--- a/core/res/res/values-mcc440-mnc20/config.xml
+++ b/core/res/res/values-mcc440-mnc20/config.xml
@@ -23,6 +23,6 @@
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
-    <integer name="config_mobile_mtu">1340</integer>
+    <integer name="config_mobile_mtu">1422</integer>
 
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 2e584e5..6eae123 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lese telefonstatus og -identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lar appen bruke enhetens telefonfunksjoner. Med denne tillatelsen kan appen finne telefonnummer og enhets-ID-er, registrere om en samtale pågår, og se det eksterne nummeret det opprettes en forbindelse med via oppringing."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"lese nøyaktige telefontilstander"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gir appen tillatelse til å bruke nøyaktige telefontilstander. Denne tillatelsen gjør at appen kan fastslå den faktiske anropstatusen, om et anrop er aktivt eller i bakgrunnen, anropsfeil, nøyaktig status for datatilkobling og datatilkoblingsfeil."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gir appen tilgang til nøyaktige telefontilstander. Denne tillatelsen gjør at appen kan fastslå den faktiske anropstatusen, om et anrop er aktivt eller i bakgrunnen, anropsfeil, nøyaktig status for datatilkobling og datatilkoblingsfeil."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"hindre nettbrettet fra å gå over til sovemodus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"forhindre telefonen fra å sove"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lar appen hindre nettbrettet fra å gå over i sovemodus."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e0433a6..7610c06 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -423,7 +423,7 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite aplicaţiei să utilizeze orice decodor media instalat pentru a decodifica redarea."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestionarea acreditărilor de încredere"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite aplicației să instaleze și să dezinstaleze certificate CA ca acreditări de încredere."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"rulați aplicația în timp ce dispozitivul este inactiv"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"rulează aplicația în timp ce dispozitivul este inactiv"</string>
     <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Cu această permisiune, sistemul Android poate rula aplicația în fundal în timp ce dispozitivul nu este utilizat."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"citire/scriere în resursele deţinute de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite aplicaţiei să citească şi să scrie în orice resursă deţinută de grupul diag, de ex., fişierele din /dev. Această permisiune ar putea să afecteze stabilitatea şi securitatea sistemului. Permisiunea trebuie utilizată NUMAI de producător sau de operator pentru diagnostice specifice pentru hardware."</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"citeşte starea şi identitatea telefonului"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicaţiei să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicaţia stabileşte numărul de telefon şi ID-urile de dispozitiv, dacă un apel este activ, precum şi numărul de la distanţă conectat printr-un apel."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"accesați stările exacte ale telefonului"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite aplicației să acceseze stările exacte ale telefonului. Cu această permisiune, aplicația poate să determine starea reală a apelului, dacă apelul este activ sau în fundal, dacă apelul nu reușește, starea exactă și întreruperile conexiunii de date."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite aplicației să acceseze stările exacte ale telefonului. Cu această permisiune, aplicația poate să determine starea reală a apelului, dacă apelul este activ sau în fundal, dacă apelul eșuează, starea exactă și întreruperile conexiunii de date."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"împiedicarea computerului tablet PC să intre în repaus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"împiedicare intrare telefon în repaus"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite aplicaţiei să împiedice intrarea tabletei în stare de repaus."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 6d8aca7..2ffc435 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Приложение сможет использовать любой установленный дешифратор."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Управление учетными данными"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Приложение сможет устанавливать сертификаты ЦС в качестве надежных учетных данных, а также удалять их."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"запуск приложений в свящем режиме"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Система Android сможет запускать приложение в фоновом режиме, когда устройство не будет использоваться."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"выполнение приложения в спящем режиме"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Система Android сможет выполнять приложение в фоновом режиме, когда устройство не используется."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Чтение/запись данных в системы диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Включение/отключение компонентов приложения"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 1d5772b..d3934a9 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -190,7 +190,7 @@
     <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Prístup k zariadeniam a sieťam prostredníctvom rozhrania Bluetooth."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Nastavenia zvuku"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Zmena nastavení zvuku."</string>
-    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Má vplyv na batériu"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Vplyv na batériu"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Používanie funkcií, ktoré môžu rýchlo vyčerpať batériu."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Priamy prístup ku kalendáru a udalostiam."</string>
@@ -232,7 +232,7 @@
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Funkcie len pre vývojárov aplikácií."</string>
     <string name="permgrouplab_display" msgid="4279909676036402636">"Používateľské rozhranie iných aplikácií"</string>
     <string name="permgroupdesc_display" msgid="6051002031933013714">"Vplyv na používateľské rozhranie ďalších aplikácií."</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Ukladací priestor"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Úložisko"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Prístup do ukl. priestoru USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Prístup na kartu SD."</string>
     <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Funkcie zjednodušenia ovládania"</string>
@@ -566,7 +566,7 @@
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čítanie presných stavov telefónu"</string>
     <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikácii pristupovať k presným stavom telefónu. Toto povolenie umožňuje aplikácii zistiť skutočný stav hovoru, či je hovor aktívny alebo na pozadí, zlyhania hovorov, presný stav dátového pripojenia a zlyhania dátového pripojenia."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zabránenie prechodu tabletu do režimu spánku"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zabránenie prechodu telefónu do režimu spánku"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"deaktivácia režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikácii zabrániť prechodu tabletu do režimu spánku."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje aplikácii zabrániť prechodu telefónu do režimu spánku."</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"infračervený prenos"</string>
@@ -637,7 +637,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Umožňuje aplikácii zobraziť informácie o konfigurácii Bluetooth na telefóne. Taktiež jej umožňuje nadväzovať a akceptovať spojenia so spárovanými zariadeniami."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"ovládať technológiu Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikácii komunikovať so značkami, kartami a čítačkami s podporou technológie Near Field Communication (NFC)."</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"zakázať uzamknutie obrazovky"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivácia zámky obrazovky"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikácii zakázať uzamknutie klávesnice a akékoľvek súvisiace zabezpečenie heslom. Príkladom je zakázanie uzamknutia klávesnice pri prichádzajúcom telefonickom hovore a jeho opätovné povolenie po skončení hovoru."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čítanie nastavení synchronizácie"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikácii čítať nastavenia synchronizácie v účte. Môže napríklad určiť, či je s účtom synchronizovaná aplikácia Ľudia."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5e8c45b..783b0a4 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -424,7 +424,7 @@
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje preverjenih poverilnic"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Aplikaciji dovoli nameščanje in odstranjevanje potrdil overitelja potrdil kot preverjenih poverilnic."</string>
     <string name="permlab_bindIdleService" msgid="816311765497613780">"izvajanje aplikacije ob nedejavnosti"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dovoljenje sistemu Android omogoča, da izvaja aplikacijo v ozadju, ko se naprava ne uporablja."</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dovoljenje sistemu Android omogoča, da izvaja aplikacijo v ozadju, ko naprava ni v uporabi."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"branje/pisanje v sredstva, ki so v lasti skupine za diagnostiko"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Programu omogoča branje in pisanje na poljuben vir, ki je v lasti skupine za diagnostiko; na primer datoteke v mapi /dev. To lahko vpliva na stabilnost in varnost sistema. To naj uporablja SAMO izdelovalec ali operater za diagnostiko, specifično za strojno opremo."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 7cbe055..d6f7457 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1461,7 +1461,7 @@
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Gränsen för data via Wi-Fi har överskridits"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> över angiven gräns."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"Bakgrundsdata är begränsade"</string>
-    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att radera begränsning"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att ta bort begränsning"</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"Säkerhetscertifikat"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certifikatet är giltigt."</string>
     <string name="issued_to" msgid="454239480274921032">"Utfärdad till:"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 87afca6..7f17c76 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Huruhusu programu kutumia vyombo vyovyote vya habari vilivyosakinishwa ili kusimbua kwa ajili ya kucheza tena."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"dhibiti vitambulisho vinavyoaminika"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Huruhusu programu kusakinisha na kusanidua vyeti vya CA kama vitambulisho vinavyoaminika."</string>
-    <string name="permlab_bindIdleService" msgid="816311765497613780">"endesha programu wakati haifanyi kitu"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ruhusa hii huwezesha mfumo wa Android kuendesha programu chini chini wakati kifaa hakitumiki."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"endesha programu wakati kifaa hakifanyi kitu"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ruhusa hii huwezesha mfumo wa Android kuendesha programu chini kwa chini wakati kifaa hakitumiki."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"soma/andika kwa vyanzo vinavyomilikiwa na diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Inaruhusu programu kusoma na kuandika kwa chanzo chochote kinachomilikiwa na kikundi cha diag; kwa mfano, faili katika /dev. Hii inaweza kuathiri udhabiti na usalama wa mfumo. Hii inapaswa kutumiwa TU kwa utambuzi mahsusi wa maunzi na mtengenezaji au opareta."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"wezesha au lemeza vijenzi vya programu"</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"kusoma hali na kitambulisho cha simu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya mbali iliyounganishwa kwa simu."</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Soma hali sahihi ya simu"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Huruhusu programu kufikia hali sahihi ya simu. Ruhusa hii huwezesha programu kufahamu hali sahihi ya simu, iwapo simu inatumika au katika hali ya chini chini, simu inaposhindikana, hali sahihi ya muunganisho wa data na muunganisho wa data unaposhindikana."</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Huruhusu programu kufikia hali sahihi ya simu. Ruhusa hii huwezesha programu kufahamu hali sahihi ya simu, iwapo simu inatumika au iko katika hali ya chini kwa chini, simu inaposhindikana, hali sahihi ya muunganisho wa data na muunganisho wa data unaposhindikana."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"kuzuia simu isilale"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 08308c7..f59b2d1 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1363,7 +1363,7 @@
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"แตะเพื่อออกจากโหมดรถยนต์"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
     <string name="tethered_notification_message" msgid="6857031760103062982">"แตะเพื่อตั้งค่า"</string>
-    <string name="back_button_label" msgid="2300470004503343439">"ย้อนกลับ"</string>
+    <string name="back_button_label" msgid="2300470004503343439">"กลับ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ถัดไป"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ข้าม"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"การใช้งานข้อมูลมือถือในระดับสูง"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d5ea7e2..4b5e48a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -424,7 +424,7 @@
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"quản lý thông tin xác thực đáng tin cậy"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Cho phép ứng dụng cài đặt và gỡ cài đặt chứng chỉ CA dưới dạng thông tin xác thực đáng tin cậy."</string>
     <string name="permlab_bindIdleService" msgid="816311765497613780">"chạy ứng dụng trong thời gian rảnh"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Sự cho phép này cho phép hệ thống Android chạy ứng dụng trong nền khi thiết bị không được sử dụng."</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Quyền này cho phép hệ thống Android chạy ứng dụng trong nền khi thiết bị không được sử dụng."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"đọc/ghi vào tài nguyên do chẩn đoán sở hữu"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và tính bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể của nhà sản xuất hoặc nhà cung cấp."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 9d3879b..ebf11c4 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -76,7 +76,7 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"默认显示本机号码,在下一次通话中也显示"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"未提供服务。"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"您无法更改来电显示设置。"</string>
-    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"访问受限情况已发生变化"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"网络可用情况发生变化"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"数据服务已禁用。"</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"紧急服务已禁用。"</string>
     <string name="RestrictedOnNormal" msgid="4953867011389750673">"已禁用语音服务。"</string>
@@ -564,7 +564,7 @@
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"读取手机状态和身份"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允许该应用访问设备的电话功能。此权限可让该应用确定本机号码和设备 ID、是否正处于通话状态以及拨打的号码。"</string>
     <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"读取确切的手机状态"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允许应用获取确切的手机状态。此权限可让应用确定实际通话状态、通话是在界面上进行还是在后台进行、通话未接通次数、确切的数据网络连接状态,以及数据网络连接失败次数。"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允许应用获取确切的手机状态。此权限可让应用确定实际通话状态、通话是在界面上进行还是在后台进行、通话未接通情况、确切的数据网络连接状态,以及数据网络连接失败情况。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"阻止平板电脑进入休眠状态"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手机休眠"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用阻止平板电脑进入休眠状态。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d079ac5..ad2f63c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -563,8 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允許應用程式控制裝置的電話功能。擁有這項權限的應用程式可在未通知您的情況下,任意切換網路、開啟或關閉手機無線電等。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"讀取手機狀態和識別碼"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限可讓應用程式判讀手機號碼和裝置 ID、是否正在通話中,以及所撥打的對方號碼。"</string>
-    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取精確手機狀態"</string>
-    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取精確的手機狀態。這項權限可讓應用程式判別實際通話狀態、通話程序正在進行中或是在背景運作、通話失敗次數、精確數據連線狀態和數據連線失敗次數。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取手機精確狀態"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取手機的精確狀態。這項權限可讓應用程式判別實際通話狀態,包括通話正在進行中或是在背景運作、通話失敗次數、精確數據連線狀態和數據連線失敗次數。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"防止平板電腦進入休眠狀態"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入待命狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index d1fa082..f01f10e 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -77,8 +77,6 @@
        <item>@drawable/btn_default_disabled_focused_holo_dark</item>
        <item>@drawable/btn_default_holo_dark</item>
        <item>@drawable/btn_default_holo_light</item>
-       <item>@drawable/btn_default_quantum_dark</item>
-       <item>@drawable/btn_default_quantum_light</item>
        <item>@drawable/btn_star_off_normal_holo_light</item>
        <item>@drawable/btn_star_on_normal_holo_light</item>
        <item>@drawable/btn_star_on_disabled_holo_light</item>
@@ -136,8 +134,6 @@
        <item>@drawable/expander_group_holo_light</item>
        <item>@drawable/list_selector_holo_dark</item>
        <item>@drawable/list_selector_holo_light</item>
-       <item>@drawable/list_selector_quantum_light</item>
-       <item>@drawable/list_selector_quantum_dark</item>
        <item>@drawable/list_section_divider_holo_light</item>
        <item>@drawable/list_section_divider_holo_dark</item>
        <item>@drawable/menu_hardkey_panel_holo_dark</item>
@@ -263,8 +259,6 @@
        <item>@drawable/ab_solid_shadow_holo</item>
        <item>@drawable/item_background_holo_dark</item>
        <item>@drawable/item_background_holo_light</item>
-       <item>@drawable/item_background_quantum_light</item>
-       <item>@drawable/item_background_quantum_dark</item>
        <item>@drawable/fastscroll_thumb_holo</item>
        <item>@drawable/fastscroll_thumb_pressed_holo</item>
        <item>@drawable/fastscroll_thumb_default_holo</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index bfd7565..039bd07 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -673,6 +673,8 @@
         <!-- Action bar styles   -->
         <!-- =================== -->
         <eat-comment />
+        <!-- Theme override for the Action Bar -->
+        <attr name="actionBarTheme" format="reference" />
         <!-- Default style for tabs within an action bar -->
         <attr name="actionBarTabStyle" format="reference" />
         <attr name="actionBarTabBarStyle" format="reference" />
@@ -2357,8 +2359,8 @@
         <!-- Sets whether or not this ViewGroup should be treated as a single entity
              when doing an Activity transition. Typically, the elements inside a
              ViewGroup are each transitioned from the scene individually. The default
-             for a ViewGroup is false unless it has a background.
-             See {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)}
+             for a ViewGroup is false unless it has a background. See
+             {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.view.View, String)}
              for more information. -->
         <attr name="transitionGroup" format="boolean" />
     </declare-styleable>
@@ -4760,14 +4762,6 @@
         <attr name="fromScene" format="reference" />
         <!-- The destination scene in this scene change. -->
         <attr name="toScene" format="reference" />
-        <!-- The name of the originating scene in this scene change.
-             Apps should treat this name as an API in the same sense
-             that an Intent action or extra key is. -->
-        <attr name="fromSceneName" format="string" />
-        <!-- The name of the destination scene in this scene change.
-             Apps should treat this name as an API in the same sense
-             that an Intent action or extra key is. -->
-        <attr name="toSceneName" format="string" />
     </declare-styleable>
 
     <!-- ========================== -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 4647413..2efbca2 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -259,6 +259,17 @@
          applications can request this feature. Default value is false. -->
     <attr name="requiredForAllUsers" format="boolean" />
 
+    <!-- Flag to specifiy for which types of profile this application needs to be present.
+         Only pre-installed applications can request this feature. Default is none. -->
+    <attr name="requiredForProfile">
+        <!-- This application needs to be present for restricted profiles -->
+        <flag name="restricted" value="0x0001" />
+        <!-- This application needs to be present for managed profiles -->
+        <flag name="managed" value="0x0002" />
+        <!-- This application needs to be present for all types of profiles -->
+        <flag name="all" value="0xFFFF" />
+    </attr>
+
     <!-- Flag indicating whether the application can be debugged, even when
          running on a device that is running in user mode. -->
     <attr name="debuggable" format="boolean" />
@@ -901,6 +912,7 @@
         <attr name="hasCode" format="boolean" />
         <attr name="persistent" />
         <attr name="requiredForAllUsers" />
+        <attr name="requiredForProfile" />
         <!-- Specify whether the components in this application are enabled or not (that is, can be
              instantiated by the system).
              If "false", it overrides any component specific values (a value of "true" will not
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
index b623263..c8083f4 100644
--- a/core/res/res/values/colors_quantum.xml
+++ b/core/res/res/values/colors_quantum.xml
@@ -15,34 +15,150 @@
 -->
 
 <resources>
-    <color name="background_quantum_dark">#ff000000</color>
-    <color name="background_quantum_light">#fff3f3f3</color>
+    <color name="background_quantum_dark">@color/black</color>
+    <color name="background_quantum_light">@color/quantum_grey_50</color>
+    <color name="secondary_background_quantum_dark">@color/quantum_grey_700</color>
+    <color name="secondary_background_quantum_light">@color/quantum_grey_100</color>
 
     <color name="bright_foreground_quantum_dark">@color/background_quantum_light</color>
     <color name="bright_foreground_quantum_light">@color/background_quantum_dark</color>
-    <color name="bright_foreground_disabled_quantum_dark">#ff4c4c4c</color>
-    <color name="bright_foreground_disabled_quantum_light">#ffb2b2b2</color>
+    <!-- TODO: This is 50% alpha black -->
+    <color name="bright_foreground_disabled_quantum_dark">#80000000</color>
+    <!-- TODO: This is 50% alpha grey_50 -->
+    <color name="bright_foreground_disabled_quantum_light">#80fafafa</color>
     <color name="bright_foreground_inverse_quantum_dark">@color/bright_foreground_quantum_light</color>
     <color name="bright_foreground_inverse_quantum_light">@color/bright_foreground_quantum_dark</color>
 
-    <color name="dim_foreground_quantum_dark">#bebebe</color>
-    <color name="dim_foreground_quantum_light">#323232</color>
+    <color name="dim_foreground_quantum_dark">#ffbebebe</color>
+    <color name="dim_foreground_quantum_light">#ff323232</color>
     <color name="dim_foreground_disabled_quantum_dark">#80bebebe</color>
     <color name="dim_foreground_disabled_quantum_light">#80323232</color>
 
-    <color name="hint_foreground_quantum_dark">#808080</color>
-    <color name="hint_foreground_quantum_light">#808080</color>
-    <color name="highlighted_text_quantum_dark">#6633b5e5</color>
-    <color name="highlighted_text_quantum_light">#6633b5e5</color>
+    <!-- TODO: These should be theme attributes. -->
+    <color name="control_normal_foreground_quantum_light">@color/secondary_text_quantum_light</color>
+    <color name="control_activated_foreground_quantum_light">@color/quantum_teal_700</color>
 
-    <color name="timepicker_default_background_quantum_dark">#ff303030</color>
-    <color name="timepicker_default_background_quantum_light">@color/white</color>
-    <color name="timepicker_default_text_color_quantum_dark">@color/white</color>
-    <color name="timepicker_default_text_color_quantum_light">#8c8c8c</color>
-    <color name="timepicker_default_disabled_color_quantum_dark">#7f08c8c8</color>
-    <color name="timepicker_default_disabled_color_quantum_light">#7f000000</color>
-    <color name="timepicker_default_ampm_selected_background_color_quantum_dark">@color/holo_blue_light</color>
-    <color name="timepicker_default_ampm_selected_background_color_quantum_light">@color/holo_blue_light</color>
+    <!-- TODO: These should be theme attributes. -->
+    <color name="control_normal_foreground_quantum_dark">@color/secondary_text_quantum_dark</color>
+    <color name="control_activated_foreground_quantum_dark">@color/quantum_lime_A200</color>
+
+    <!-- TODO: These should be theme attributes. -->
+    <color name="btn_default_normal_quantum_light">@color/quantum_grey_300</color>
+    <color name="btn_default_pressed_quantum_light">@color/quantum_grey_500</color>
+
+    <!-- TODO: These should be theme attributes. -->
+    <color name="btn_default_normal_quantum_dark">@color/quantum_grey_700</color>
+    <color name="btn_default_pressed_quantum_dark">@color/quantum_grey_500</color>
+
+    <color name="hint_foreground_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
+    <color name="hint_foreground_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
+    <!-- TODO: This is 40% alpha lime_A200 -->
+    <color name="highlighted_text_quantum_dark">#66eeff41</color>
+    <!-- TODO: This is 40% alpha teal_700 -->
+    <color name="highlighted_text_quantum_light">#660097a7</color>
+
+    <!-- TODO: These should all be pushed into a TimePicker widget style. -->
+    <color name="timepicker_default_background_quantum_dark">@color/background_quantum_dark</color>
+    <color name="timepicker_default_background_quantum_light">@color/background_quantum_light</color>
+    <color name="timepicker_default_text_color_quantum_dark">@color/bright_foreground_quantum_dark</color>
+    <color name="timepicker_default_text_color_quantum_light">@color/bright_foreground_quantum_light</color>
+    <color name="timepicker_default_disabled_color_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
+    <color name="timepicker_default_disabled_color_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
+    <color name="timepicker_default_ampm_selected_background_color_quantum_dark">@color/control_activated_foreground_quantum_dark</color>
+    <color name="timepicker_default_ampm_selected_background_color_quantum_light">@color/control_activated_foreground_quantum_light</color>
     <color name="timepicker_default_ampm_unselected_background_color_quantum_dark">@color/transparent</color>
     <color name="timepicker_default_ampm_unselected_background_color_quantum_light">@color/white</color>
+
+    <!-- Primary & accent colors -->
+
+    <color name="quantum_red_100">#fff4c7c3</color>
+    <color name="quantum_red_300">#ffe67c73</color>
+    <color name="quantum_red_500">#ffdb4437</color>
+    <color name="quantum_red_700">#ffc53929</color>
+    <color name="quantum_red_A200">#ffff5252</color>
+    <color name="quantum_red_A400">#ffff1744</color>
+
+    <color name="quantum_blue_100">#ffc6dafc</color>
+    <color name="quantum_blue_300">#ff7baaf7</color>
+    <color name="quantum_blue_500">#ff4285f4</color>
+    <color name="quantum_blue_700">#ff3367d6</color>
+    <color name="quantum_blue_A200">#ff448aff</color>
+    <color name="quantum_blue_A400">#ff2979ff</color>
+
+    <color name="quantum_teal_100">#ffb2ebf2</color>
+    <color name="quantum_teal_300">#ff4dd0e1</color>
+    <color name="quantum_teal_500">#ff00bcd4</color>
+    <color name="quantum_teal_700">#ff0097a7</color>
+    <color name="quantum_teal_A200">#ff18ffff</color>
+    <color name="quantum_teal_A400">#ff00e5ff</color>
+
+    <color name="quantum_green_100">#ffb7e1cd</color>
+    <color name="quantum_green_300">#ff57bb8a</color>
+    <color name="quantum_green_500">#ff0f9d58</color>
+    <color name="quantum_green_700">#ff0b8043</color>
+    <color name="quantum_green_A200">#ff69f0ae</color>
+    <color name="quantum_green_A400">#ff00e676</color>
+
+    <color name="quantum_lime_100">#fff0f4c3</color>
+    <color name="quantum_lime_300">#ffdce775</color>
+    <color name="quantum_lime_500">#ffcddc39</color>
+    <color name="quantum_lime_700">#ffafb42b</color>
+    <color name="quantum_lime_A200">#ffeeff41</color>
+    <color name="quantum_lime_A400">#ffc6ff00</color>
+
+    <color name="quantum_yellow_100">#fffce8b2</color>
+    <color name="quantum_yellow_300">#fff7cb4d</color>
+    <color name="quantum_yellow_500">#fff4b400</color>
+    <color name="quantum_yellow_700">#fff09300</color>
+    <color name="quantum_yellow_A200">#ffffcd40</color>
+    <color name="quantum_yellow_A400">#ffffbc00</color>
+
+    <color name="quantum_orange_100">#ffffe0b2</color>
+    <color name="quantum_orange_300">#ffffb74d</color>
+    <color name="quantum_orange_500">#ffff9800</color>
+    <color name="quantum_orange_700">#fff57c00</color>
+    <color name="quantum_orange_A200">#ffffab40</color>
+    <color name="quantum_orange_A400">#ffff9100</color>
+
+    <color name="quantum_deep_orange_100">#fff4c7c3</color>
+    <color name="quantum_deep_orange_300">#ffe67c73</color>
+    <color name="quantum_deep_orange_500">#ffff5722</color>
+    <color name="quantum_deep_orange_700">#ffc53929</color>
+    <color name="quantum_deep_orange_A200">#ffff5252</color>
+    <color name="quantum_deep_orange_A400">#ffff1744</color>
+
+    <!-- Neutral colors -->
+
+    <color name="quantum_grey_50">#fffafafa</color>
+    <color name="quantum_grey_100">#fff5f5f5</color>
+    <color name="quantum_grey_300">#ffeeeeee</color>
+    <color name="quantum_grey_500">#ffa3a3a3</color>
+    <color name="quantum_grey_700">#ff717171</color>
+
+    <color name="quantum_blue_grey_50">#ffeceff1</color>
+    <color name="quantum_blue_grey_100">#ffcfd8dc</color>
+    <color name="quantum_blue_grey_300">#ff90a4ae</color>
+    <color name="quantum_blue_grey_500">#ff607d8b</color>
+    <color name="quantum_blue_grey_700">#ff455a64</color>
+
+    <color name="quantum_brown_100">#ffd7ccc8</color>
+    <color name="quantum_brown_300">#ffa1887f</color>
+    <color name="quantum_brown_500">#ff795548</color>
+    <color name="quantum_brown_700">#ff5d4037</color>
+
+    <!-- Text & foreground colors -->
+
+    <color name="primary_text_quantum_light">#ff000000</color>
+    <color name="secondary_text_quantum_light">#de000000</color>
+    <color name="tertiary_text_quantum_light">#8a000000</color>
+
+    <color name="primary_text_quantum_dark">#ffffffff</color>
+    <color name="secondary_text_quantum_dark">#deffffff</color>
+    <color name="tertiary_text_quantum_dark">#8affffff</color>
+
+    <!-- "Theme" colors to be replaced by attrs when available -->
+    <color name="theme_color_100">@color/quantum_teal_100</color>
+    <color name="theme_color_300">@color/quantum_teal_300</color>
+    <color name="theme_color_500">@color/quantum_teal_500</color>
+    <color name="theme_color_700">@color/quantum_teal_700</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 519e2ae..8d68277 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1083,8 +1083,16 @@
     <!-- Name of the wimax state tracker clas -->
     <string name="config_wimaxStateTrackerClassname" translatable="false"></string>
 
-    <!-- Is the dreams feature supported? -->
+    <!-- Specifies whether the dreams feature should be supported.
+         When true, the system will allow the user to configure dreams (screensavers)
+         to launch when a user activity timeout occurs or the system is told to nap.
+         When false, the dreams feature will be disabled (this does not affect dozing).
+
+         Consider setting this resource to false or disabling dreams by default when a
+         doze component is specified below since dreaming will supercede dozing and
+         will prevent the system from entering a low power state until the dream ends. -->
     <bool name="config_dreamsSupported">true</bool>
+
     <!-- If supported, are dreams enabled? (by default) -->
     <bool name="config_dreamsEnabledByDefault">true</bool>
     <!-- If supported and enabled, are dreams activated when docked? (by default) -->
@@ -1181,6 +1189,8 @@
 
     <!--  Maximum number of supported users -->
     <integer name="config_multiuserMaximumUsers">1</integer>
+    <!-- Whether UI for multi user should be shown -->
+    <bool name="config_enableMultiUserUI">false</bool>
 
     <!-- Minimum span needed to begin a touch scaling gesture.
          If the span is equal to or greater than this size, a scaling gesture
diff --git a/core/res/res/values/dimens_quantum.xml b/core/res/res/values/dimens_quantum.xml
new file mode 100644
index 0000000..3913752
--- /dev/null
+++ b/core/res/res/values/dimens_quantum.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+
+    <!-- Default height of an action bar. -->
+    <dimen name="action_bar_default_height_quantum">56dp</dimen>
+    <!-- Vertical padding around action bar icons. -->
+    <dimen name="action_bar_icon_vertical_padding_quantum">16dp</dimen>
+    <!-- Text size for action bar titles -->
+    <dimen name="action_bar_title_text_size_quantum">20sp</dimen>
+    <!-- Text size for action bar subtitles -->
+    <dimen name="action_bar_subtitle_text_size_quantum">16sp</dimen>
+    <!-- Top margin for action bar subtitles -->
+    <dimen name="action_bar_subtitle_top_margin_quantum">-3dp</dimen>
+    <!-- Bottom margin for action bar subtitles -->
+    <dimen name="action_bar_subtitle_bottom_margin_quantum">5dp</dimen>
+
+    <dimen name="text_size_display_4_quantum">112sp</dimen>
+    <dimen name="text_size_display_3_quantum">56sp</dimen>
+    <dimen name="text_size_display_2_quantum">45sp</dimen>
+    <dimen name="text_size_display_1_quantum">34sp</dimen>
+    <dimen name="text_size_headline_quantum">24sp</dimen>
+    <dimen name="text_size_title_quantum">20sp</dimen>
+    <dimen name="text_size_subhead_quantum">16sp</dimen>
+    <dimen name="text_size_body_2_quantum">14sp</dimen>
+    <dimen name="text_size_body_1_quantum">14sp</dimen>
+    <dimen name="text_size_caption_quantum">12sp</dimen>
+    <dimen name="text_size_menu_quantum">14sp</dimen>
+    <dimen name="text_size_button_quantum">14sp</dimen>
+
+</resources>
diff --git a/core/res/res/values/donottranslate_quantum.xml b/core/res/res/values/donottranslate_quantum.xml
new file mode 100644
index 0000000..83cc4e5
--- /dev/null
+++ b/core/res/res/values/donottranslate_quantum.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <string name="font_family_display_4_quantum">sans-serif-light</string>
+    <string name="font_family_display_3_quantum">sans-serif</string>
+    <string name="font_family_display_2_quantum">sans-serif</string>
+    <string name="font_family_display_1_quantum">sans-serif</string>
+    <string name="font_family_headline_quantum">sans-serif</string>
+    <string name="font_family_title_quantum">sans-serif-medium</string>
+    <string name="font_family_subhead_quantum">sans-serif</string>
+    <string name="font_family_body_2_quantum">sans-serif-medium</string>
+    <string name="font_family_body_1_quantum">sans-serif</string>
+    <string name="font_family_caption_quantum">sans-serif</string>
+    <string name="font_family_menu_quantum">sans-serif-medium</string>
+    <string name="font_family_button_quantum">sans-serif</string>
+
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 44ad5ee..3106daa 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2103,11 +2103,10 @@
   <public type="attr" name="controlY1" />
   <public type="attr" name="controlX2" />
   <public type="attr" name="controlY2" />
-  <public type="attr" name="fromSceneName" />
-  <public type="attr" name="toSceneName" />
   <public type="attr" name="sharedElementName" />
   <public type="attr" name="transitionGroup" />
   <public type="attr" name="castsShadow" />
+  <public type="attr" name="requiredForProfile"/>
 
   <public type="id" name="shared_element_name" />
 
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index df850a7..44cdb5f 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -88,47 +88,48 @@
 
     <!-- Begin Quantum theme styles -->
 
-    <!-- Text Styles -->
+    <!-- Text styles -->
+
     <style name="TextAppearance.Quantum" parent="TextAppearance"/>
 
     <style name="TextAppearance.Quantum.Inverse" parent="TextAppearance.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Large" parent="TextAppearance.Large"/>
 
+    <style name="TextAppearance.Quantum.Large.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
     <style name="TextAppearance.Quantum.Medium" parent="TextAppearance.Medium"/>
 
+    <style name="TextAppearance.Quantum.Medium.Inverse">
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
     <style name="TextAppearance.Quantum.Small" parent="TextAppearance.Small"/>
 
-    <style name="TextAppearance.Quantum.Large.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Medium.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
-    </style>
-
     <style name="TextAppearance.Quantum.Small.Inverse">
-        <item name="textColor">?textColorSecondaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.SearchResult">
         <item name="textStyle">normal</item>
-        <item name="textColor">?textColorPrimary</item>
-        <item name="textColorHint">?textColorHint</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textColorHint">?attr/textColorHint</item>
     </style>
 
     <style name="TextAppearance.Quantum.SearchResult.Title">
@@ -137,54 +138,26 @@
 
     <style name="TextAppearance.Quantum.SearchResult.Subtitle">
         <item name="textSize">14sp</item>
-        <item name="textColor">?textColorSecondary</item>
+        <item name="textColor">?attr/textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget" parent="TextAppearance.Widget"/>
 
-    <style name="TextAppearance.Quantum.Widget.Button" parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="textColor">@color/primary_text_light_nodisable</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
-        <item name="textColor">?textColorPrimary</item>
-    </style>
-
-    <!-- This style is for smaller screens; values-xlarge defines a version
-         for larger screens. -->
-    <style name="TextAppearance.Quantum.Widget.TabWidget">
-        <item name="textSize">14sp</item>
+    <style name="TextAppearance.Quantum.Widget.Button">
+        <item name="fontFamily">@string/font_family_button_quantum</item>
+        <item name="textSize">@dimen/text_size_button_quantum</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">?attr/textColorPrimary</item>
         <item name="textStyle">normal</item>
-        <item name="textColor">@color/tab_indicator_text</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.TextView">
-        <item name="textColor">?textColorPrimaryDisableOnly</item>
-        <item name="textColorHint">?textColorHint</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
-        <item name="textSize">18sp</item>
-        <item name="textColor">?textColorPrimaryDisableOnly</item>
-        <item name="textColorHint">?textColorHint</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.DropDownHint">
-        <item name="textColor">?textColorPrimary</item>
-        <item name="textSize">14sp</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.DropDownItem">
-        <item name="textColor">?textColorPrimaryDisableOnly</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem">
-        <item name="textColor">?textColorPrimaryDisableOnly</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.EditText">
-        <item name="textColor">@color/bright_foreground_light</item>
-        <item name="textColorHint">@color/hint_foreground_quantum_light</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.Switch" parent="TextAppearance.Quantum.Small">
+        <item name="textColor">@color/secondary_text_quantum_dark</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.PopupMenu" parent="TextAppearance.Widget.PopupMenu">
@@ -199,75 +172,89 @@
         <item name="textSize">14sp</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Title"
-           parent="TextAppearance.Quantum.Medium">
-        <item name="textSize">@dimen/action_bar_title_text_size</item>
+    <style name="TextAppearance.Quantum.Widget.DropDownHint">
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">14sp</item>
+    </style>
+    <style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
+        <item name="textColor">?attr/textColorPrimary</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle"
-           parent="TextAppearance.Quantum.Small">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
+    <!-- This style is for smaller screens; values-xlarge defines a version
+         for larger screens. -->
+    <style name="TextAppearance.Quantum.Widget.TabWidget">
+        <item name="textSize">14sp</item>
+        <item name="textStyle">normal</item>
+        <item name="textColor">@color/tab_indicator_text</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse"
-           parent="TextAppearance.Quantum.Medium.Inverse">
-        <item name="textSize">@dimen/action_bar_title_text_size</item>
+    <style name="TextAppearance.Quantum.Widget.TextView">
+        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
+        <item name="textColorHint">?attr/textColorHint</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse"
-           parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
+    <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
+        <item name="textSize">18sp</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionBar.Menu"
-           parent="TextAppearance.Quantum.Small">
+    <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem" />
+
+    <style name="TextAppearance.Quantum.Widget.DropDownItem">
+        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode"/>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Medium">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Small">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <!-- Text styles with no light versions -->
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Title" parent="TextAppearance.Quantum.Medium">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" parent="TextAppearance.Quantum.Small">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Small">
         <item name="textSize">12sp</item>
         <item name="textStyle">bold</item>
         <item name="textColor">?attr/actionMenuTextColor</item>
         <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionMode"/>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Title"
-           parent="TextAppearance.Quantum.Medium">
-        <item name="textSize">@dimen/action_bar_title_text_size</item>
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
     </style>
 
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle"
-           parent="TextAppearance.Quantum.Small">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse"
-           parent="TextAppearance.Quantum.Medium.Inverse">
-        <item name="textSize">@dimen/action_bar_title_text_size</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse"
-           parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Widget.Switch" parent="TextAppearance.Quantum.Small">
-        <!-- Switch thumb asset presents a dark background. -->
-        <item name="textColor">@color/secondary_text_quantum_dark</item>
-    </style>
-
-    <style name="TextAppearance.Quantum.Light.Widget.Switch" parent="TextAppearance.Quantum.Small">
-        <!-- Switch thumb asset presents a dark background. -->
-        <item name="textColor">@color/primary_text_quantum_dark</item>
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
     </style>
 
     <style name="TextAppearance.Quantum.WindowTitle">
-        <item name="textColor">#fff</item>
+        <item name="textColor">?attr/textColorPrimary</item>
         <item name="textSize">14sp</item>
         <item name="textStyle">bold</item>
     </style>
 
     <style name="TextAppearance.Quantum.DialogWindowTitle">
         <item name="textSize">22sp</item>
-        <item name="textColor">@color/holo_blue_light</item>
+        <item name="textColor">?attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView">
@@ -277,12 +264,7 @@
     <!-- Light text styles -->
     <style name="TextAppearance.Quantum.Light" parent="TextAppearance.Quantum"/>
 
-    <style name="TextAppearance.Quantum.Light.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.Inverse" parent="TextAppearance.Quantum.Inverse" />
 
     <style name="TextAppearance.Quantum.Light.Large" parent="TextAppearance.Quantum.Large"/>
 
@@ -290,48 +272,26 @@
 
     <style name="TextAppearance.Quantum.Light.Small" parent="TextAppearance.Quantum.Small"/>
 
-    <style name="TextAppearance.Quantum.Light.Large.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.Large.Inverse" parent="TextAppearance.Quantum.Large.Inverse" />
 
-    <style name="TextAppearance.Quantum.Light.Medium.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.Medium.Inverse" parent="TextAppearance.Quantum.Medium.Inverse" />
 
-    <style name="TextAppearance.Quantum.Light.Small.Inverse">
-        <item name="textColor">?textColorPrimaryInverse</item>
-        <item name="textColorHint">?textColorHintInverse</item>
-        <item name="textColorHighlight">?textColorHighlightInverse</item>
-        <item name="textColorLink">?textColorLinkInverse</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.Small.Inverse" parent="TextAppearance.Quantum.Small.Inverse" />
 
-    <style name="TextAppearance.Quantum.Light.SearchResult" parent="TextAppearance.Quantum.SearchResult">
-        <item name="textColor">?textColorPrimary</item>
-        <item name="textColorHint">?textColorHint</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.SearchResult" parent="TextAppearance.Quantum.SearchResult" />
 
-    <style name="TextAppearance.Quantum.Light.SearchResult.Title">
-        <item name="textSize">18sp</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.SearchResult.Title" parent="TextAppearance.Quantum.SearchResult.Title" />
 
-    <style name="TextAppearance.Quantum.Light.SearchResult.Subtitle">
-        <item name="textSize">14sp</item>
-        <item name="textColor">?textColorSecondary</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.SearchResult.Subtitle" parent="TextAppearance.Quantum.SearchResult.Subtitle" />
 
     <style name="TextAppearance.Quantum.Light.Widget" parent="TextAppearance.Widget"/>
 
-    <style name="TextAppearance.Quantum.Light.Widget.Button"/>
+    <style name="TextAppearance.Quantum.Light.Widget.Button" parent="TextAppearance.Quantum.Widget.Button" />
 
-    <style name="TextAppearance.Quantum.Light.Widget.EditText">
-        <item name="textColor">@color/bright_foreground_dark</item>
-        <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
+    <style name="TextAppearance.Quantum.Light.Widget.EditText" parent="TextAppearance.Quantum.Widget.EditText" />
+
+    <style name="TextAppearance.Quantum.Light.Widget.Switch" parent="TextAppearance.Quantum.Small">
+        <item name="textColor">@color/secondary_text_quantum_dark</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Widget.PopupMenu" parent="TextAppearance.Quantum.Widget.PopupMenu"/>
@@ -346,57 +306,59 @@
 
     <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle"/>
 
-    <style name="TextAppearance.Quantum.Light.WindowTitle">
-        <item name="textColor">#fff</item>
-        <item name="textSize">14sp</item>
-        <item name="textStyle">bold</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.WindowTitle" parent="TextAppearance.Quantum.WindowTitle" />
 
-    <style name="TextAppearance.Quantum.Light.DialogWindowTitle">
-        <item name="textSize">22sp</item>
-        <item name="textColor">@color/holo_blue_light</item>
-    </style>
+    <style name="TextAppearance.Quantum.Light.DialogWindowTitle" parent="TextAppearance.Quantum.DialogWindowTitle" />
 
     <style name="TextAppearance.Quantum.Light.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView"/>
 
     <!-- Widget Styles -->
 
-    <style name="Widget.Quantum" parent="Widget"/>
 
     <style name="Quantum" />
     <style name="Quantum.Light" />
 
+    <style name="Widget.Quantum" parent="Widget" />
+
+    <!-- Bordered ink button -->
     <style name="Widget.Quantum.Button" parent="Widget.Button">
         <item name="background">@drawable/btn_default_quantum_dark</item>
-        <item name="textAppearance">?attr/textAppearanceMedium</item>
-        <item name="textColor">@color/primary_text_quantum_dark</item>
+        <item name="textAppearance">?attr/textAppearanceButton</item>
         <item name="minHeight">48dip</item>
-        <item name="minWidth">64dip</item>
+        <item name="minWidth">96dip</item>
     </style>
 
-    <style name="Widget.Quantum.StackView">
-        <item name="resOutColor">@color/holo_blue_light</item>
-        <item name="clickColor">@color/holo_blue_light</item>
-    </style>
-
-    <style name="Widget.Quantum.Button.Borderless">
-        <item name="background">?attr/selectableItemBackground</item>
-        <item name="paddingStart">4dip</item>
-        <item name="paddingEnd">4dip</item>
-    </style>
-
-    <style name="Widget.Quantum.Button.Borderless.Small">
-        <item name="textSize">14sp</item>
-    </style>
-
+    <!-- Small bordered ink button -->
     <style name="Widget.Quantum.Button.Small">
-        <item name="background">@drawable/btn_default_quantum_dark</item>
-        <item name="textAppearance">?attr/textAppearanceSmall</item>
-        <item name="textColor">@color/primary_text_quantum_dark</item>
         <item name="minHeight">48dip</item>
         <item name="minWidth">48dip</item>
     </style>
 
+    <!-- Bordered paper button -->
+    <style name="Widget.Quantum.Button.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
+
+    <!-- Bordered paper button with color -->
+    <style name="Widget.Quantum.Button.Paper.Color">
+        <item name="background">@drawable/btn_color_quantum_dark</item>
+    </style>
+
+    <!-- Borderless ink button -->
+    <style name="Widget.Quantum.Button.Borderless">
+        <item name="background">@drawable/btn_borderless_quantum_dark</item>
+    </style>
+
+    <!-- Small borderless ink button -->
+    <style name="Widget.Quantum.Button.Borderless.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Borderless paper button -->
+    <style name="Widget.Quantum.Button.Borderless.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
     <style name="Widget.Quantum.Button.Inset">
         <item name="background">@drawable/button_inset</item>
     </style>
@@ -405,7 +367,6 @@
         <item name="background">@drawable/btn_toggle_holo_dark</item>
         <item name="textOn">@string/capital_on</item>
         <item name="textOff">@string/capital_off</item>
-        <item name="disabledAlpha">?attr/disabledAlpha</item>
         <item name="textAppearance">?attr/textAppearanceSmall</item>
         <item name="minHeight">48dip</item>
     </style>
@@ -430,12 +391,17 @@
         <item name="dividerPadding">0dp</item>
     </style>
 
+    <style name="Widget.Quantum.StackView">
+        <item name="resOutColor">@color/holo_blue_light</item>
+        <item name="clickColor">@color/holo_blue_light</item>
+    </style>
+
     <style name="Widget.Quantum.TextView" parent="Widget.TextView"/>
 
     <style name="Widget.Quantum.CheckedTextView" parent="Widget.CheckedTextView"/>
 
     <style name="Widget.Quantum.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
-        <item name="background">@drawable/list_section_divider_holo_dark</item>
+        <item name="background">@drawable/list_section_divider_quantum_dark</item>
         <item name="textAllCaps">true</item>
     </style>
 
@@ -446,8 +412,8 @@
     <style name="Widget.Quantum.AbsListView" parent="Widget.AbsListView"/>
 
     <style name="Widget.Quantum.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
-        <item name="dropDownSelector">@drawable/list_selector_quantum_dark</item>
-        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_dark</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
+        <item name="popupBackground">?attr/colorBackground</item>
     </style>
 
     <style name="Widget.Quantum.CompoundButton" parent="Widget.CompoundButton"/>
@@ -459,7 +425,7 @@
     <style name="Widget.Quantum.EditText" parent="Widget.EditText"/>
 
     <style name="Widget.Quantum.ExpandableListView" parent="Widget.Quantum.ListView">
-        <item name="groupIndicator">@drawable/expander_group_holo_dark</item>
+        <item name="groupIndicator">@drawable/expander_group_quantum_dark</item>
         <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
         <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
         <item name="childDivider">?attr/listDivider</item>
@@ -545,7 +511,7 @@
     </style>
 
     <style name="Widget.Quantum.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
-        <item name="progressDrawable">@drawable/progress_horizontal_holo_dark</item>
+        <item name="progressDrawable">@drawable/progress_horizontal_quantum_dark</item>
         <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
         <item name="minHeight">16dip</item>
         <item name="maxHeight">16dip</item>
@@ -569,11 +535,11 @@
 
     <style name="Widget.Quantum.SeekBar">
         <item name="indeterminateOnly">false</item>
-        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_holo_dark</item>
-        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_holo_dark</item>
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum_dark</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum_dark</item>
         <item name="minHeight">13dip</item>
         <item name="maxHeight">13dip</item>
-        <item name="thumb">@drawable/scrubber_control_selector_holo</item>
+        <item name="thumb">@drawable/scrubber_control_selector_quantum_dark</item>
         <item name="thumbOffset">16dip</item>
         <item name="focusable">true</item>
         <item name="paddingStart">16dip</item>
@@ -607,9 +573,9 @@
     <style name="Widget.Quantum.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
 
     <style name="Widget.Quantum.Spinner" parent="Widget.Spinner.DropDown">
-        <item name="background">@drawable/spinner_background_holo_dark</item>
-        <item name="dropDownSelector">@drawable/list_selector_quantum_dark</item>
-        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_dark</item>
+        <item name="background">@drawable/spinner_background_quantum_dark</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
+        <item name="popupBackground">?attr/colorBackground</item>
         <item name="dropDownVerticalOffset">0dip</item>
         <item name="dropDownHorizontalOffset">0dip</item>
         <item name="dropDownWidth">wrap_content</item>
@@ -621,11 +587,11 @@
     <style name="Widget.Quantum.Spinner.DropDown"/>
 
     <style name="Widget.Quantum.Spinner.DropDown.ActionBar">
-        <item name="background">@drawable/spinner_ab_holo_dark</item>
+        <item name="background">@drawable/spinner_background_quantum_dark</item>
     </style>
 
     <style name="Widget.Quantum.CompoundButton.Star" parent="Widget.CompoundButton.Star">
-        <item name="button">@drawable/btn_star_holo_dark</item>
+        <item name="button">@drawable/btn_star_quantum_dark</item>
     </style>
 
     <style name="Widget.Quantum.TabWidget" parent="Widget.TabWidget">
@@ -640,7 +606,7 @@
     </style>
 
     <style name="Widget.Quantum.Tab" parent="Widget.Quantum.ActionBar.TabView">
-        <item name="background">@drawable/tab_indicator_holo</item>
+        <item name="background">@drawable/tab_indicator_quantum_dark</item>
         <item name="layout_width">0dip</item>
         <item name="layout_weight">1</item>
         <item name="minWidth">80dip</item>
@@ -683,8 +649,8 @@
     <style name="Widget.Quantum.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
 
     <style name="Widget.Quantum.ListPopupWindow" parent="Widget.ListPopupWindow">
-        <item name="dropDownSelector">@drawable/list_selector_quantum_dark</item>
-        <item name="popupBackground">@drawable/menu_panel_holo_dark</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
+        <item name="popupBackground">?attr/colorBackground</item>
         <item name="dropDownVerticalOffset">0dip</item>
         <item name="dropDownHorizontalOffset">0dip</item>
         <item name="dropDownWidth">wrap_content</item>
@@ -708,7 +674,7 @@
     </style>
 
     <style name="Widget.Quantum.ActionButton.Overflow">
-        <item name="src">@drawable/ic_menu_moreoverflow_holo_dark</item>
+        <item name="src">@drawable/ic_menu_moreoverflow_quantum_dark</item>
         <item name="background">?attr/actionBarItemBackground</item>
         <item name="contentDescription">@string/action_menu_overflow_description</item>
     </style>
@@ -716,7 +682,7 @@
     <style name="Widget.Quantum.ActionButton.TextButton" parent="Widget.Quantum.ButtonBar.Button"/>
 
     <style name="Widget.Quantum.ActionBar.TabView" parent="Widget.ActionBar.TabView">
-        <item name="background">@drawable/tab_indicator_ab_holo</item>
+        <item name="background">@drawable/tab_indicator_quantum_dark</item>
         <item name="paddingStart">16dip</item>
         <item name="paddingEnd">16dip</item>
     </style>
@@ -749,7 +715,7 @@
     <style name="Widget.Quantum.ActionBar" parent="Widget.ActionBar">
         <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
         <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="background">@drawable/ab_transparent_dark_holo</item>
+        <item name="background">@drawable/ab_transparent_quantum_dark</item>
         <item name="backgroundStacked">@drawable/ab_stacked_transparent_dark_holo</item>
         <item name="backgroundSplit">@drawable/ab_bottom_transparent_dark_holo</item>
         <item name="divider">?attr/dividerVertical</item>
@@ -773,53 +739,65 @@
     </style>
 
     <style name="Widget.Quantum.CompoundButton.Switch">
-        <item name="track">@drawable/switch_track_holo_dark</item>
-        <item name="thumb">@drawable/switch_inner_holo_dark</item>
+        <item name="track">@drawable/switch_track_quantum_dark</item>
+        <item name="thumb">@drawable/switch_inner_quantum_dark</item>
         <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
-        <item name="textOn">@string/capital_on</item>
-        <item name="textOff">@string/capital_off</item>
+        <item name="textOn"></item>
+        <item name="textOff"></item>
         <item name="thumbTextPadding">12dip</item>
-        <item name="switchMinWidth">96dip</item>
+        <item name="switchMinWidth">72dip</item>
         <item name="switchPadding">16dip</item>
     </style>
 
     <!-- Light widget styles -->
 
-    <style name="Widget.Quantum.Light"/>
+    <style name="Widget.Quantum.Light" parent="Widget" />
 
-    <style name="Widget.Quantum.Light.Button" parent="Widget.Button">
+    <!-- Bordered ink button -->
+    <style name="Widget.Quantum.Light.Button" parent="Widget.Quantum.Button">
         <item name="background">@drawable/btn_default_quantum_light</item>
-        <item name="textAppearance">?attr/textAppearanceMediumInverse</item>
-        <item name="textColor">@color/primary_text_quantum_light</item>
+        <item name="textAppearance">?attr/textAppearanceButton</item>
         <item name="minHeight">48dip</item>
-        <item name="minWidth">64dip</item>
+        <item name="minWidth">96dip</item>
     </style>
 
-    <style name="Widget.Quantum.Light.Button.Borderless">
-        <item name="background">?attr/selectableItemBackground</item>
-        <item name="paddingStart">4dip</item>
-        <item name="paddingEnd">4dip</item>
-    </style>
-
-    <style name="Widget.Quantum.Light.Button.Borderless.Small">
-        <item name="textSize">14sp</item>
-    </style>
-
+    <!-- Small bordered ink button -->
     <style name="Widget.Quantum.Light.Button.Small">
-        <item name="background">@drawable/btn_default_quantum_light</item>
-        <item name="textAppearance">?attr/textAppearanceSmall</item>
-        <item name="textColor">@color/primary_text_quantum_light</item>
         <item name="minHeight">48dip</item>
         <item name="minWidth">48dip</item>
     </style>
 
+    <!-- Bordered paper button -->
+    <style name="Widget.Quantum.Light.Button.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
+
+    <!-- Bordered paper button with color -->
+    <style name="Widget.Quantum.Light.Button.Paper.Color">
+        <item name="background">@drawable/btn_color_quantum_light</item>
+    </style>
+
+    <!-- Borderless ink button -->
+    <style name="Widget.Quantum.Light.Button.Borderless">
+        <item name="background">@drawable/btn_borderless_quantum_light</item>
+    </style>
+
+    <!-- Small borderless ink button -->
+    <style name="Widget.Quantum.Light.Button.Borderless.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Borderless paper button -->
+    <style name="Widget.Quantum.Light.Button.Borderless.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
     <style name="Widget.Quantum.Light.Button.Inset"/>
 
     <style name="Widget.Quantum.Light.Button.Toggle">
         <item name="background">@drawable/btn_toggle_holo_light</item>
         <item name="textOn">@string/capital_on</item>
         <item name="textOff">@string/capital_off</item>
-        <item name="disabledAlpha">?attr/disabledAlpha</item>
         <item name="textAppearance">?attr/textAppearanceSmall</item>
         <item name="minHeight">48dip</item>
     </style>
@@ -840,7 +818,7 @@
     <style name="Widget.Quantum.Light.CheckedTextView" parent="Widget.CheckedTextView"/>
 
     <style name="Widget.Quantum.Light.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
-        <item name="background">@drawable/list_section_divider_holo_light</item>
+        <item name="background">@drawable/list_section_divider_quantum_light</item>
         <item name="textAllCaps">true</item>
     </style>
 
@@ -851,8 +829,8 @@
     <style name="Widget.Quantum.Light.AbsListView" parent="Widget.AbsListView"/>
 
     <style name="Widget.Quantum.Light.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
-        <item name="dropDownSelector">@drawable/list_selector_quantum_light</item>
-        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_light</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_light</item>
+        <item name="popupBackground">?attr/colorBackground</item>
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox"/>
@@ -862,7 +840,7 @@
     <style name="Widget.Quantum.Light.EditText" parent="Widget.Quantum.EditText"/>
 
     <style name="Widget.Quantum.Light.ExpandableListView" parent="Widget.Quantum.Light.ListView">
-        <item name="groupIndicator">@drawable/expander_group_holo_light</item>
+        <item name="groupIndicator">@drawable/expander_group_quantum_light</item>
         <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
         <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
         <item name="childDivider">?attr/listDivider</item>
@@ -930,7 +908,7 @@
     <style name="Widget.Quantum.Light.ProgressBar" parent="Widget.Quantum.ProgressBar"/>
 
     <style name="Widget.Quantum.Light.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal">
-        <item name="progressDrawable">@drawable/progress_horizontal_holo_light</item>
+        <item name="progressDrawable">@drawable/progress_horizontal_quantum_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.ProgressBar.Small" parent="Widget.Quantum.ProgressBar.Small"/>
@@ -946,8 +924,9 @@
     <style name="Widget.Quantum.Light.ProgressBar.Large.Inverse" parent="Widget.Quantum.ProgressBar.Large.Inverse"/>
 
     <style name="Widget.Quantum.Light.SeekBar" parent="Widget.Quantum.SeekBar">
-        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>
-        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum_light</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum_light</item>
+        <item name="thumb">@drawable/scrubber_control_selector_quantum_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.RatingBar" parent="Widget.RatingBar">
@@ -976,9 +955,9 @@
     <style name="Widget.Quantum.Light.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
 
     <style name="Widget.Quantum.Light.Spinner" parent="Widget.Quantum.Spinner">
-        <item name="background">@drawable/spinner_background_holo_light</item>
-        <item name="dropDownSelector">@drawable/list_selector_quantum_light</item>
-        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_light</item>
+        <item name="background">@drawable/spinner_background_quantum_light</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_light</item>
+        <item name="popupBackground">?attr/colorBackground</item>
         <item name="dropDownVerticalOffset">0dip</item>
         <item name="dropDownHorizontalOffset">0dip</item>
         <item name="dropDownWidth">wrap_content</item>
@@ -988,11 +967,11 @@
     <style name="Widget.Quantum.Light.Spinner.DropDown"/>
 
     <style name="Widget.Quantum.Light.Spinner.DropDown.ActionBar">
-        <item name="background">@drawable/spinner_ab_holo_light</item>
+        <item name="background">@drawable/spinner_background_quantum_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
-        <item name="button">@drawable/btn_star_holo_light</item>
+        <item name="button">@drawable/btn_star_quantum_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.TabWidget" parent="Widget.Quantum.TabWidget"/>
@@ -1022,8 +1001,8 @@
     <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
 
     <style name="Widget.Quantum.Light.ListPopupWindow" parent="Widget.ListPopupWindow">
-        <item name="dropDownSelector">@drawable/list_selector_quantum_light</item>
-        <item name="popupBackground">@drawable/menu_panel_holo_light</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_light</item>
+        <item name="popupBackground">?attr/colorBackground</item>
         <item name="dropDownVerticalOffset">0dip</item>
         <item name="dropDownHorizontalOffset">0dip</item>
         <item name="dropDownWidth">wrap_content</item>
@@ -1034,14 +1013,15 @@
     <style name="Widget.Quantum.Light.ActionButton" parent="Widget.Quantum.ActionButton"/>
 
     <style name="Widget.Quantum.Light.ActionButton.Overflow">
-        <item name="src">@drawable/ic_menu_moreoverflow_holo_light</item>
+        <item name="src">@drawable/ic_menu_moreoverflow_quantum_light</item>
         <item name="contentDescription">@string/action_menu_overflow_description</item>
     </style>
 
-    <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView"/>
+    <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView">
+        <item name="background">@drawable/tab_indicator_quantum_light</item>
+    </style>
 
     <style name="Widget.Quantum.Light.Tab" parent="Widget.Quantum.Light.ActionBar.TabView">
-        <item name="background">@drawable/tab_indicator_holo</item>
         <item name="layout_width">0dip</item>
         <item name="layout_weight">1</item>
         <item name="minWidth">80dip</item>
@@ -1076,10 +1056,10 @@
     <style name="Widget.Quantum.Light.ActionBar" parent="Widget.Quantum.ActionBar">
         <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
         <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="background">@drawable/ab_transparent_light_holo</item>
+        <item name="background">@drawable/ab_transparent_quantum_light</item>
         <item name="backgroundStacked">@drawable/ab_stacked_transparent_light_holo</item>
         <item name="backgroundSplit">@drawable/ab_bottom_transparent_light_holo</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_light</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_light</item>
         <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
         <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
     </style>
@@ -1103,7 +1083,7 @@
         <item name="background">@drawable/ab_solid_dark_holo</item>
         <item name="backgroundStacked">@drawable/ab_stacked_solid_dark_holo</item>
         <item name="backgroundSplit">@drawable/ab_bottom_solid_inverse_holo</item>
-        <item name="divider">@drawable/list_divider_holo_dark</item>
+        <item name="divider">@drawable/list_divider_quantum_dark</item>
         <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
         <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
         <item name="progressBarPadding">32dip</item>
@@ -1111,11 +1091,11 @@
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.CompoundButton.Switch">
-        <item name="track">@drawable/switch_track_holo_light</item>
-        <item name="thumb">@drawable/switch_inner_holo_light</item>
+        <item name="track">@drawable/switch_track_quantum_light</item>
+        <item name="thumb">@drawable/switch_inner_quantum_light</item>
         <item name="switchTextAppearance">@style/TextAppearance.Quantum.Light.Widget.Switch</item>
-        <item name="textOn">@string/capital_on</item>
-        <item name="textOff">@string/capital_off</item>
+        <item name="textOn"></item>
+        <item name="textOff"></item>
         <item name="thumbTextPadding">12dip</item>
         <item name="switchMinWidth">96dip</item>
         <item name="switchPadding">16dip</item>
@@ -1132,16 +1112,16 @@
     <!-- Dialog styles -->
 
     <style name="AlertDialog.Quantum" parent="AlertDialog">
-        <item name="fullDark">@drawable/dialog_full_holo_dark</item>
-        <item name="topDark">@drawable/dialog_top_holo_dark</item>
-        <item name="centerDark">@drawable/dialog_middle_holo_dark</item>
-        <item name="bottomDark">@drawable/dialog_bottom_holo_dark</item>
-        <item name="fullBright">@drawable/dialog_full_holo_dark</item>
-        <item name="topBright">@drawable/dialog_top_holo_dark</item>
-        <item name="centerBright">@drawable/dialog_middle_holo_dark</item>
-        <item name="bottomBright">@drawable/dialog_bottom_holo_dark</item>
-        <item name="bottomMedium">@drawable/dialog_bottom_holo_dark</item>
-        <item name="centerMedium">@drawable/dialog_middle_holo_dark</item>
+        <item name="fullDark">?attr/colorBackground</item>
+        <item name="topDark">?attr/colorBackground</item>
+        <item name="centerDark">?attr/colorBackground</item>
+        <item name="bottomDark">?attr/colorBackground</item>
+        <item name="fullBright">?attr/colorBackground</item>
+        <item name="topBright">?attr/colorBackground</item>
+        <item name="centerBright">?attr/colorBackground</item>
+        <item name="bottomBright">?attr/colorBackground</item>
+        <item name="bottomMedium">?attr/colorBackground</item>
+        <item name="centerMedium">?attr/colorBackground</item>
         <item name="layout">@layout/alert_dialog_holo</item>
         <item name="listLayout">@layout/select_dialog_holo</item>
         <item name="progressLayout">@layout/progress_dialog_holo</item>
@@ -1151,18 +1131,7 @@
         <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_holo</item>
     </style>
 
-    <style name="AlertDialog.Quantum.Light">
-        <item name="fullDark">@drawable/dialog_full_holo_light</item>
-        <item name="topDark">@drawable/dialog_top_holo_light</item>
-        <item name="centerDark">@drawable/dialog_middle_holo_light</item>
-        <item name="bottomDark">@drawable/dialog_bottom_holo_light</item>
-        <item name="fullBright">@drawable/dialog_full_holo_light</item>
-        <item name="topBright">@drawable/dialog_top_holo_light</item>
-        <item name="centerBright">@drawable/dialog_middle_holo_light</item>
-        <item name="bottomBright">@drawable/dialog_bottom_holo_light</item>
-        <item name="bottomMedium">@drawable/dialog_bottom_holo_light</item>
-        <item name="centerMedium">@drawable/dialog_middle_holo_light</item>
-    </style>
+    <style name="AlertDialog.Quantum.Light" />
 
     <!-- Window title -->
     <style name="WindowTitleBackground.Quantum">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b1bf781..9f368c4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -289,6 +289,7 @@
   <java-symbol type="bool" name="config_useFixedVolume" />
   <java-symbol type="bool" name="config_forceDefaultOrientation" />
   <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
+  <java-symbol type="bool" name="config_enableMultiUserUI"/>
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index f0db46c..d2eee28 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -49,42 +49,31 @@
         <item name="disabledAlpha">0.5</item>
         <item name="backgroundDimAmount">0.6</item>
 
-        <item name="colorPressedHighlight">@color/holo_gray_light</item>
-        <item name="colorLongPressedHighlight">@color/holo_gray_bright</item>
-        <item name="colorFocusedHighlight">@color/holo_blue_dark</item>
-        <item name="colorMultiSelectHighlight">@color/holo_green_light</item>
-        <item name="colorActivatedHighlight">@color/holo_blue_dark</item>
-
         <!-- Text styles -->
         <item name="textAppearance">@style/TextAppearance.Quantum</item>
         <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
 
         <item name="textColorPrimary">@color/primary_text_quantum_dark</item>
-        <item name="textColorSecondary">@color/secondary_text_quantum_dark</item>
-        <item name="textColorTertiary">@color/tertiary_text_quantum_dark</item>
         <item name="textColorPrimaryInverse">@color/primary_text_quantum_light</item>
-        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_light</item>
-        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_light</item>
         <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
-        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_light</item>
-        <item name="textColorPrimaryNoDisable">@color/primary_text_nodisable_quantum_dark</item>
-        <item name="textColorSecondaryNoDisable">@color/secondary_text_nodisable_quantum_dark</item>
-        <item name="textColorPrimaryInverseNoDisable">@color/primary_text_nodisable_quantum_light</item>
-        <item name="textColorSecondaryInverseNoDisable">@color/secondary_text_nodisable_quantum_light</item>
+        <item name="textColorSecondary">@color/secondary_text_quantum_dark</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_light</item>
+        <item name="textColorTertiary">@color/tertiary_text_quantum_dark</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_light</item>
         <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
         <item name="textColorHintInverse">@color/hint_foreground_quantum_light</item>
-        <item name="textColorSearchUrl">@color/search_url_text_quantum_dark</item>
         <item name="textColorHighlight">@color/highlighted_text_quantum_dark</item>
         <item name="textColorHighlightInverse">@color/highlighted_text_quantum_light</item>
-        <item name="textColorLink">@color/holo_blue_light</item>
-        <item name="textColorLinkInverse">@color/holo_blue_light</item>
+        <item name="textColorLink">@color/quantum_teal_500</item>
+        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_quantum_dark</item>
         <item name="textColorAlertDialogListItem">@color/primary_text_quantum_dark</item>
 
         <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Large</item>
-        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Medium</item>
-        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Small</item>
         <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Large.Inverse</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Medium</item>
         <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Medium.Inverse</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Small</item>
         <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Small.Inverse</item>
         <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.SearchResult.Title</item>
         <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.SearchResult.Subtitle</item>
@@ -92,7 +81,7 @@
         <item name="textAppearanceButton">@style/TextAppearance.Quantum.Widget.Button</item>
 
         <item name="editTextColor">?attr/textColorPrimary</item>
-        <item name="editTextBackground">@drawable/edit_text_holo_dark</item>
+        <item name="editTextBackground">@drawable/edit_text_quantum_dark</item>
 
         <item name="candidatesTextStyleSpans">@string/candidates_style</item>
 
@@ -104,17 +93,16 @@
 
         <!-- Button styles -->
         <item name="buttonStyle">@style/Widget.Quantum.Button</item>
-
         <item name="buttonStyleSmall">@style/Widget.Quantum.Button.Small</item>
         <item name="buttonStyleInset">@style/Widget.Quantum.Button.Inset</item>
-
         <item name="buttonStyleToggle">@style/Widget.Quantum.Button.Toggle</item>
+
         <item name="switchStyle">@style/Widget.Quantum.CompoundButton.Switch</item>
         <item name="mediaRouteButtonStyle">@style/Widget.Quantum.MediaRouteButton</item>
 
         <item name="selectableItemBackground">@drawable/item_background_quantum_dark</item>
         <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_dark</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_dark</item>
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
@@ -129,17 +117,17 @@
 
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
-        <item name="listDivider">@drawable/list_divider_holo_dark</item>
+        <item name="listDivider">@drawable/list_divider_quantum_dark</item>
         <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.TextView.ListSeparator</item>
 
-        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_holo_dark</item>
-        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_holo_dark</item>
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_dark</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_dark</item>
 
-        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_quantum_dark</item>
+        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_holo_dark</item>
 
-        <item name="activatedBackgroundIndicator">@drawable/activated_background_holo_dark</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum_dark</item>
 
-        <item name="listDividerAlertDialog">@drawable/list_divider_holo_dark</item>
+        <item name="listDividerAlertDialog">@drawable/list_divider_quantum_dark</item>
 
         <item name="expandableListPreferredItemPaddingLeft">40dip</item>
         <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
@@ -148,8 +136,8 @@
         <item name="expandableListPreferredItemIndicatorRight">0dip</item>
         <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
         <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
-        <item name="findOnPageNextDrawable">@drawable/ic_find_next_holo_dark</item>
-        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_holo_dark</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum_dark</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum_dark</item>
 
         <!-- Gallery attributes -->
         <item name="galleryItemBackground">@drawable/gallery_item_background</item>
@@ -182,7 +170,7 @@
         <item name="alertDialogTheme">@style/Theme.Quantum.Dialog.Alert</item>
         <item name="alertDialogStyle">@style/AlertDialog.Quantum</item>
         <item name="alertDialogCenterButtons">false</item>
-        <item name="alertDialogIcon">@drawable/ic_dialog_alert_holo_dark</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum_dark</item>
 
         <!-- Presentation attributes -->
         <item name="presentationTheme">@style/Theme.Quantum.Dialog.Presentation</item>
@@ -191,7 +179,7 @@
         <item name="toastFrameBackground">@drawable/toast_frame</item>
 
         <!-- Panel attributes -->
-        <item name="panelBackground">@drawable/menu_hardkey_panel_holo_dark</item>
+        <item name="panelBackground">?attr/colorBackground</item>
         <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
         <!-- These three attributes do not seems to be used by the framework. Declared public though -->
         <item name="panelColorBackground">#000</item>
@@ -206,8 +194,8 @@
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item>
         <item name="scrollbarSize">10dip</item>
-        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_holo_dark</item>
-        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_holo_dark</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum_dark</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum_dark</item>
         <item name="scrollbarTrackHorizontal">@null</item>
         <item name="scrollbarTrackVertical">@null</item>
 
@@ -217,7 +205,7 @@
         <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
         <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
         <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.TextSuggestionsPopupWindow</item>
-        <item name="textCursorDrawable">@drawable/text_cursor_holo_dark</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_quantum_dark</item>
 
         <!-- Widget styles -->
         <item name="absListViewStyle">@style/Widget.Quantum.AbsListView</item>
@@ -291,7 +279,7 @@
         <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
         <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
         <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
-        <item name="detailsElementBackground">@drawable/panel_bg_holo_dark</item>
+        <item name="detailsElementBackground">?attr/colorBackground</item>
 
         <!-- Search widget styles -->
         <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
@@ -300,9 +288,9 @@
         <item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
         <item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
         <item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
-        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_dark</item>
-        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_holo_dark</item>
+        <item name="actionModeBackground">@color/theme_color_700</item>
+        <item name="actionModeSplitBackground">@color/theme_color_700</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum_dark</item>
         <item name="actionBarTabStyle">@style/Widget.Quantum.ActionBar.TabView</item>
         <item name="actionBarTabBarStyle">@style/Widget.Quantum.ActionBar.TabBar</item>
         <item name="actionBarTabTextStyle">@style/Widget.Quantum.ActionBar.TabText</item>
@@ -312,14 +300,15 @@
         <item name="actionBarSize">@dimen/action_bar_default_height</item>
         <item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
         <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarItemBackground">@drawable/item_background_borderless_quantum_dark</item>
 
-        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_holo_dark</item>
-        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_holo_dark</item>
-        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_holo_dark</item>
-        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_dark</item>
-        <item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_dark</item>
-        <item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_dark</item>
-        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_holo_dark</item>
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum_dark</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum_dark</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum_dark</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum_dark</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum_dark</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum_dark</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum_dark</item>
 
         <item name="dividerVertical">?attr/listDivider</item>
         <item name="dividerHorizontal">?attr/listDivider</item>
@@ -359,12 +348,12 @@
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Quantum.DatePicker</item>
 
-        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
+        <!-- TODO: This belongs in a FastScroll style -->
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum_light</item>
         <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
         <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
-        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_holo_dark</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum_dark</item>
         <item name="fastScrollOverlayPosition">atThumb</item>
-
     </style>
 
     <!-- Quantum Paper theme (light version). -->
@@ -376,42 +365,32 @@
         <item name="disabledAlpha">0.5</item>
         <item name="backgroundDimAmount">0.6</item>
 
-        <item name="colorPressedHighlight">@color/holo_gray_light</item>
-        <item name="colorLongPressedHighlight">@color/holo_gray_bright</item>
-        <item name="colorFocusedHighlight">@color/holo_blue_dark</item>
-        <item name="colorMultiSelectHighlight">@color/holo_green_light</item>
-        <item name="colorActivatedHighlight">@color/holo_blue_dark</item>
-
         <!-- Text styles -->
         <item name="textAppearance">@style/TextAppearance.Quantum.Light</item>
         <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Light.Inverse</item>
 
         <item name="textColorPrimary">@color/primary_text_quantum_light</item>
-        <item name="textColorSecondary">@color/secondary_text_quantum_light</item>
-        <item name="textColorTertiary">@color/tertiary_text_quantum_light</item>
         <item name="textColorPrimaryInverse">@color/primary_text_quantum_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_quantum_light</item>
         <item name="textColorSecondaryInverse">@color/secondary_text_quantum_dark</item>
+        <item name="textColorTertiary">@color/tertiary_text_quantum_light</item>
         <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_dark</item>
         <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_light</item>
         <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
-        <item name="textColorPrimaryNoDisable">@color/primary_text_nodisable_quantum_light</item>
-        <item name="textColorSecondaryNoDisable">@color/secondary_text_nodisable_quantum_light</item>
-        <item name="textColorPrimaryInverseNoDisable">@color/primary_text_nodisable_quantum_dark</item>
-        <item name="textColorSecondaryInverseNoDisable">@color/secondary_text_nodisable_quantum_dark</item>
         <item name="textColorHint">@color/hint_foreground_quantum_light</item>
         <item name="textColorHintInverse">@color/hint_foreground_quantum_dark</item>
-        <item name="textColorSearchUrl">@color/search_url_text_quantum_light</item>
         <item name="textColorHighlight">@color/highlighted_text_quantum_light</item>
         <item name="textColorHighlightInverse">@color/highlighted_text_quantum_dark</item>
-        <item name="textColorLink">@color/holo_blue_light</item>
-        <item name="textColorLinkInverse">@color/holo_blue_light</item>
+        <item name="textColorLink">@color/quantum_teal_500</item>
+        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_quantum_light</item>
         <item name="textColorAlertDialogListItem">@color/primary_text_quantum_light</item>
 
         <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Light.Large</item>
-        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Light.Medium</item>
-        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Light.Small</item>
         <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Light.Large.Inverse</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Light.Medium</item>
         <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Light.Medium.Inverse</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Light.Small</item>
         <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Light.Small.Inverse</item>
         <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.Light.SearchResult.Title</item>
         <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.Light.SearchResult.Subtitle</item>
@@ -419,7 +398,7 @@
         <item name="textAppearanceButton">@style/TextAppearance.Quantum.Light.Widget.Button</item>
 
         <item name="editTextColor">?attr/textColorPrimary</item>
-        <item name="editTextBackground">@drawable/edit_text_holo_light</item>
+        <item name="editTextBackground">@drawable/edit_text_quantum_light</item>
 
         <item name="candidatesTextStyleSpans">@string/candidates_style</item>
 
@@ -441,7 +420,7 @@
 
         <item name="selectableItemBackground">@drawable/item_background_quantum_light</item>
         <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_light</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_light</item>
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
@@ -456,15 +435,15 @@
 
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
-        <item name="listDivider">@drawable/list_divider_holo_light</item>
+        <item name="listDivider">@drawable/list_divider_quantum_light</item>
         <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.Light.TextView.ListSeparator</item>
 
-        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_holo_light</item>
-        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_holo_light</item>
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_light</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_light</item>
 
-        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_quantum_light</item>
+        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_holo_light</item>
 
-        <item name="activatedBackgroundIndicator">@drawable/activated_background_holo_light</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum_light</item>
 
         <item name="expandableListPreferredItemPaddingLeft">40dip</item>
         <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
@@ -474,9 +453,9 @@
         <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
         <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
 
-        <item name="listDividerAlertDialog">@drawable/list_divider_holo_light</item>
-        <item name="findOnPageNextDrawable">@drawable/ic_find_next_holo_light</item>
-        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_holo_light</item>
+        <item name="listDividerAlertDialog">@drawable/list_divider_quantum_light</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum_light</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum_light</item>
 
         <!-- Gallery attributes -->
         <item name="galleryItemBackground">@drawable/gallery_item_background</item>
@@ -488,7 +467,7 @@
         <item name="windowFullscreen">false</item>
         <item name="windowOverscan">false</item>
         <item name="windowIsFloating">false</item>
-        <item name="windowContentOverlay">@drawable/ab_solid_shadow_holo</item>
+        <item name="windowContentOverlay">@drawable/ab_solid_shadow_qntm</item>
         <item name="windowShowWallpaper">false</item>
         <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
         <item name="windowTitleSize">25dip</item>
@@ -508,7 +487,7 @@
         <item name="alertDialogTheme">@style/Theme.Quantum.Light.Dialog.Alert</item>
         <item name="alertDialogStyle">@style/AlertDialog.Quantum.Light</item>
         <item name="alertDialogCenterButtons">false</item>
-        <item name="alertDialogIcon">@drawable/ic_dialog_alert_holo_light</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum_light</item>
 
         <!-- Presentation attributes -->
         <item name="presentationTheme">@style/Theme.Quantum.Light.Dialog.Presentation</item>
@@ -517,7 +496,7 @@
         <item name="toastFrameBackground">@drawable/toast_frame</item>
 
         <!-- Panel attributes -->
-        <item name="panelBackground">@drawable/menu_hardkey_panel_holo_light</item>
+        <item name="panelBackground">?attr/colorBackground</item>
         <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
         <!-- These three attributes do not seems to be used by the framework. Declared public though -->
         <item name="panelColorBackground">#000</item>
@@ -532,8 +511,8 @@
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item>
         <item name="scrollbarSize">10dip</item>
-        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_holo_light</item>
-        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_holo_light</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum_light</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum_light</item>
         <item name="scrollbarTrackHorizontal">@null</item>
         <item name="scrollbarTrackVertical">@null</item>
 
@@ -543,7 +522,7 @@
         <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
         <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
         <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.Light.TextSuggestionsPopupWindow</item>
-        <item name="textCursorDrawable">@drawable/text_cursor_holo_light</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_quantum_light</item>
 
         <!-- Widget styles -->
         <item name="absListViewStyle">@style/Widget.Quantum.Light.AbsListView</item>
@@ -617,7 +596,7 @@
         <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
         <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
         <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
-        <item name="detailsElementBackground">@drawable/panel_bg_holo_light</item>
+        <item name="detailsElementBackground">?attr/colorBackground</item>
 
         <!-- PreferenceFrameLayout attributes -->
         <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
@@ -631,7 +610,7 @@
         <item name="actionOverflowButtonStyle">@style/Widget.Quantum.Light.ActionButton.Overflow</item>
         <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
         <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
-        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_holo_light</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum_light</item>
         <item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView</item>
         <item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar</item>
         <item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText</item>
@@ -641,14 +620,15 @@
         <item name="actionBarSize">@dimen/action_bar_default_height</item>
         <item name="actionModePopupWindowStyle">@style/Widget.Quantum.Light.PopupWindow.ActionMode</item>
         <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarItemBackground">@drawable/item_background_borderless_quantum_light</item>
 
-        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_holo_light</item>
-        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_holo_light</item>
-        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_holo_light</item>
-        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_light</item>
-        <item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_light</item>
-        <item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_light</item>
-        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_holo_light</item>
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum_light</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum_light</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum_light</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum_light</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum_light</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum_light</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum_light</item>
 
         <item name="dividerVertical">?attr/listDivider</item>
         <item name="dividerHorizontal">?attr/listDivider</item>
@@ -685,45 +665,18 @@
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Quantum.Light.DatePicker</item>
 
-        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum_light</item>
         <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
         <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
-        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_holo_light</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum_light</item>
         <item name="fastScrollOverlayPosition">atThumb</item>
-
     </style>
 
     <!-- Variant of the quantum (light) theme that has a solid (opaque) action bar
          with an inverse color profile. The dark action bar sharply stands out against
          the light content. -->
     <style name="Theme.Quantum.Light.DarkActionBar">
-        <item name="windowContentOverlay">@drawable/ab_solid_shadow_holo</item>
-        <item name="actionBarStyle">@style/Widget.Quantum.Light.ActionBar.Solid.Inverse</item>
-        <item name="actionBarWidgetTheme">@style/Theme.Quantum</item>
-
-        <item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
-        <item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
-        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
-        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_dark</item>
-        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_holo_dark</item>
-        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_dark</item>
-        <item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView.Inverse</item>
-        <item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar.Inverse</item>
-        <item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText.Inverse</item>
-        <item name="actionBarDivider">@drawable/list_divider_holo_dark</item>
-        <item name="actionMenuTextColor">?attr/textColorPrimaryInverse</item>
-        <item name="actionModeStyle">@style/Widget.Quantum.Light.ActionMode.Inverse</item>
-        <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.ActionButton.CloseMode</item>
-        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
-
-        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_holo_dark</item>
-        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_holo_dark</item>
-        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_holo_dark</item>
-        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_dark</item>
-        <item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_dark</item>
-        <item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_dark</item>
-        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_holo_dark</item>
+        <item name="actionBarTheme">@style/Theme.Quantum</item>
     </style>
 
     <!-- Variant of the quantum (dark) theme with no action bar. -->
@@ -877,7 +830,7 @@
     <style name="Theme.Quantum.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
-        <item name="windowBackground">@drawable/dialog_full_holo_dark</item>
+        <item name="windowBackground">?attr/colorBackground</item>
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
@@ -999,7 +952,7 @@
     <style name="Theme.Quantum.Light.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
-        <item name="windowBackground">@drawable/dialog_full_holo_light</item>
+        <item name="windowBackground">?attr/colorBackground</item>
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index b942eb6..cad030a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -252,26 +252,26 @@
                 if (!validateEapValue(eapValue)) {
                     throw new SAXException();
                 }
-		if (eapValue.equals("TLS")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-		} else if (eapValue.equals("TTLS")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
-		} else if (eapValue.equals("PEAP")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
-		}
+                if (eapValue.equals("TLS")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+                } else if (eapValue.equals("TTLS")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
+                } else if (eapValue.equals("PEAP")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
+                }
                 eap = false;
             }
             if (phase2) {
                 String phase2Value = new String(ch, start, length);
-		if (phase2Value.equals("PAP")) {
+                if (phase2Value.equals("PAP")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
-		} else if (phase2Value.equals("MSCHAP")) {
+                } else if (phase2Value.equals("MSCHAP")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAP);
-		} else if (phase2Value.equals("MSCHAPV2")) {
+                } else if (phase2Value.equals("MSCHAPV2")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
-		} else if (phase2Value.equals("GTC")) {
+                } else if (phase2Value.equals("GTC")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-		}
+                }
                 phase2 = false;
             }
             if (identity) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 04ce4b7..91c3093 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -27,6 +27,7 @@
 import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.os.PowerManager;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.view.KeyEvent;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -52,6 +53,7 @@
         extends ConnectivityManagerTestBase {
     private final static String TAG = "WifiStressTest";
 
+    private final static long SCREEN_OFF_TIMER = 500; //500ms
     /**
      * Wi-Fi idle time for default sleep policy
      */
@@ -157,11 +159,11 @@
             writeOutput(String.format("average scanning time is %d", averageScanTime));
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
                     ssidAppearInScanResultsCount, i));
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             scanResultAvailable = false;
             assertTrue("start scan failed", mWifiManager.startScan());
             while (true) {
-                if ((System.currentTimeMillis() - startTime) >
+                if ((SystemClock.uptimeMillis() - startTime) >
                 WIFI_SCAN_TIMEOUT) {
                     fail("Wifi scanning takes more than " + WIFI_SCAN_TIMEOUT + " ms");
                 }
@@ -172,7 +174,7 @@
                         e.printStackTrace();
                     }
                     if (scanResultAvailable) {
-                        long scanTime = (System.currentTimeMillis() - startTime);
+                        long scanTime = (SystemClock.uptimeMillis() - startTime);
                         scanTimeSum += scanTime;
                         break;
                     }
@@ -255,8 +257,13 @@
                     i, mReconnectIterations));
             log("iteration: " + i);
             turnScreenOff();
+            // Use clock time since boot for intervals.
+            long start = SystemClock.uptimeMillis();
             PowerManager pm =
                 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+            while (pm.isScreenOn() && ((SystemClock.uptimeMillis() - start) < SCREEN_OFF_TIMER)) {
+                sleep(100, "wait for screen off");
+            }
             assertFalse(pm.isScreenOn());
             sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY, "Interruped while wait for wifi to be idle");
             assertTrue("Wait for Wi-Fi to idle timeout",
@@ -287,14 +294,14 @@
             mRunner.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
 
             // Measure the time for Wi-Fi to get connected
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             assertTrue("Wait for Wi-Fi enable timeout after wake up",
                     waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                     SHORT_TIMEOUT));
             assertTrue("Wait for Wi-Fi connection timeout after wake up",
                     waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                     WIFI_CONNECTION_TIMEOUT));
-            long connectionTime = System.currentTimeMillis() - startTime;
+            long connectionTime = SystemClock.uptimeMillis() - startTime;
             sum += connectionTime;
             log("average reconnection time is: " + sum/(i+1));
 
diff --git a/core/tests/coretests/src/android/app/TranslucentFancyActivity.java b/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
index ec5ad7a..35abaaa 100644
--- a/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
+++ b/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
@@ -53,7 +53,7 @@
      * describe what is to be displayed in the screen.
      */
     @Override
-	protected void onCreate(Bundle icicle)
+    protected void onCreate(Bundle icicle)
     {
         // Be sure to call the super class.
         super.onCreate(icicle);
diff --git a/core/tests/coretests/src/android/app/activity/AbortReceiver.java b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
index fef1775..8d5c022 100644
--- a/core/tests/coretests/src/android/app/activity/AbortReceiver.java
+++ b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
@@ -32,7 +32,7 @@
 
     public void onReceive(Context context, Intent intent)
     {
-	//Log.i("AbortReceiver", "onReceiveIntent!");
+        //Log.i("AbortReceiver", "onReceiveIntent!");
         try {
             IBinder caller = intent.getIBinderExtra("caller");
             Parcel data = Parcel.obtain();
diff --git a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
index e969d10..9f402a5 100644
--- a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
+++ b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
@@ -24,19 +24,19 @@
 import android.util.Log;
 
 public class RemoteSubActivityScreen extends SubActivityScreen {
-	Handler mHandler = new Handler();
-	boolean mFirst = false;
+    Handler mHandler = new Handler();
+    boolean mFirst = false;
 
     public RemoteSubActivityScreen() {
     }
 
     @Override
     public void onCreate(Bundle icicle) {
-    	// We are running in a remote process, so want to have the sub-activity
-    	// sending the result back in the original process.
+        // We are running in a remote process, so want to have the sub-activity
+        // sending the result back in the original process.
         Intent intent = getIntent();
-    	intent.setClass(this, SubActivityScreen.class);
-    	
+        intent.setClass(this, SubActivityScreen.class);
+        
         super.onCreate(icicle);
         
         boolean kill = intent.getBooleanExtra("kill", false);
@@ -44,16 +44,16 @@
         //        + " kill=" + kill);
         
         if (kill) {
-	        // After finishing initialization, kill the process!  But only if
-	        // this is the first time...
-	        if (icicle == null) {
-		        mHandler.post(new Runnable() {
-		        	public void run() {
-		        		handleBeforeStopping();
-		        		Process.killProcess(Process.myPid());
-		        	}
-		        });
-	        }
+            // After finishing initialization, kill the process!  But only if
+            // this is the first time...
+            if (icicle == null) {
+                mHandler.post(new Runnable() {
+                    public void run() {
+                        handleBeforeStopping();
+                        Process.killProcess(Process.myPid());
+                    }
+                });
+            }
         }
     }
 }
diff --git a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
index 919c591..3caec7a 100644
--- a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
+++ b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
@@ -44,24 +44,24 @@
         // Move on to the next thing that will generate a result...  but only
         // if we are being launched for the first time.
         if (icicle == null) {
-	        if (mMode == PENDING_RESULT_MODE) {
-	            PendingIntent apr = createPendingResult(1, null,
-	                    Intent.FILL_IN_ACTION);
-	            Intent res = new Intent();
+            if (mMode == PENDING_RESULT_MODE) {
+                PendingIntent apr = createPendingResult(1, null,
+                        Intent.FILL_IN_ACTION);
+                Intent res = new Intent();
                 res.putExtra("tkey", "tval");
                 res.setAction("test");
-	            try {
-    	            apr.send(this, RESULT_OK, res);
-	            } catch (PendingIntent.CanceledException e) {
-	            }
-	        } else if (mMode < CHILD_OFFSET) {
-	            Intent intent = new Intent();
-	        	intent.setClass(this, SubActivityScreen.class);
-	            intent.putExtra("mode", CHILD_OFFSET+mMode);
-	            //System.out.println("*** Starting from onStart: " + intent);
-	            startActivityForResult(intent, 1);
-	            return;
-	        }
+                try {
+                    apr.send(this, RESULT_OK, res);
+                } catch (PendingIntent.CanceledException e) {
+                }
+            } else if (mMode < CHILD_OFFSET) {
+                Intent intent = new Intent();
+                intent.setClass(this, SubActivityScreen.class);
+                intent.putExtra("mode", CHILD_OFFSET+mMode);
+                //System.out.println("*** Starting from onStart: " + intent);
+                startActivityForResult(intent, 1);
+                return;
+            }
         }
     }
 
@@ -77,15 +77,15 @@
         //Log.i("foo", "SubActivityScreen pid=" + Process.myPid() + " onResume");
         
         if (mMode >= CHILD_OFFSET) {
-        	// Wait a little bit, to give our parent time to kill itself
-        	// if that is something it is into.
-        	try {
-	        	Thread.sleep(500);
-        	} catch (InterruptedException e) {
-        		setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
-        		finish();
-        		return;
-        	}
+            // Wait a little bit, to give our parent time to kill itself
+            // if that is something it is into.
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
+                finish();
+                return;
+            }
             //System.out.println("Resuming sub-activity: mode=" + mMode);
             switch (mMode-CHILD_OFFSET) {
             case NO_RESULT_MODE:
diff --git a/core/tests/coretests/src/android/database/DatabaseCursorTest.java b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
index 36f0f4b..08cd027 100644
--- a/core/tests/coretests/src/android/database/DatabaseCursorTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
@@ -51,8 +51,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-	File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
-	mDatabaseFile = new File(dbDir, "database_test.db");
+        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
 
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/core/tests/coretests/src/android/database/DatabaseStatementTest.java b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
index 512d5cd..895d715 100644
--- a/core/tests/coretests/src/android/database/DatabaseStatementTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
@@ -41,8 +41,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-	File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
-	mDatabaseFile = new File(dbDir, "database_test.db");
+        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
 
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
new file mode 100644
index 0000000..9f04228
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
@@ -0,0 +1,41 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v1
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
new file mode 100644
index 0000000..c7b066d
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.framework.multidexlegacyversionedtestapp"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="9"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:name="android.support.multidex.MultiDexApplication"
+        android:allowBackup="true"
+        android:label="MultiDexLegacyVersionedTestApp_v1">
+        <activity
+            android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+            android:label="MultiDexLegacyVersionedTestApp_v1" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+                     android:label="Test for MultiDexLegacyVersionedTestApp_v1" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+    public static int getVersion() {
+        return Version.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+
+    public int getVersion() {
+        return ClassForMainDex.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..24b4d69
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+    public MultiDexUpdateTest() {
+        super(MainActivity.class);
+    }
+
+    /**
+     * Tests that all classes of the application can be loaded. Verifies also that we load the
+     * correct version of {@link Version} ie the class is the secondary dex file.
+     */
+    public void testAllClassAvailable()
+    {
+        assertEquals(1, getActivity().getVersion());
+    }
+}
diff --git a/media/java/android/media/IMediaControllerCallback.aidl b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
similarity index 61%
copy from media/java/android/media/IMediaControllerCallback.aidl
copy to core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
index b54d0cf..eb9827a 100644
--- a/media/java/android/media/IMediaControllerCallback.aidl
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2014 The Android Open Source Project
+/*
+ * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,16 +14,12 @@
  * limitations under the License.
  */
 
-package android.media;
+package com.android.framework.multidexlegacyversionedtestapp;
 
-import android.os.Bundle;
+/* can go in secondary dex */
+public class Version {
 
-/**
- * @hide
- */
-oneway interface IMediaControllerCallback {
-    void onEvent(String event, in Bundle extras);
-    void onMetadataUpdate(in Bundle metadata);
-    void onPlaybackUpdate(int newState);
-    void onRouteChanged(in Bundle route);
-}
\ No newline at end of file
+    public static int getVersion() {
+        return 1;
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
new file mode 100644
index 0000000..1b8da41
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
@@ -0,0 +1,41 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v2
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
new file mode 100644
index 0000000..4d24793
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.framework.multidexlegacyversionedtestapp"
+    android:versionCode="2"
+    android:versionName="2.0" >
+
+    <uses-sdk
+        android:minSdkVersion="9"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:name="android.support.multidex.MultiDexApplication"
+        android:allowBackup="true"
+        android:label="MultiDexLegacyVersionedTestApp_v2">
+        <activity
+            android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+            android:label="MultiDexLegacyVersionedTestApp_v2" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+                     android:label="Test for MultiDexLegacyVersionedTestApp_v2" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+    public static int getVersion() {
+        return Version.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+
+    public int getVersion() {
+        return ClassForMainDex.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..f130cb2
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+    public MultiDexUpdateTest() {
+        super(MainActivity.class);
+    }
+
+    /**
+     * Tests that all classes of the application can be loaded. Verifies also that we load the
+     * correct version of {@link Version} ie the class is the secondary dex file.
+     */
+    public void testAllClassAvailable()
+    {
+        assertEquals(2, getActivity().getVersion());
+    }
+}
diff --git a/media/java/android/media/IMediaControllerCallback.aidl b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
similarity index 61%
copy from media/java/android/media/IMediaControllerCallback.aidl
copy to core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
index b54d0cf..1f2305f 100644
--- a/media/java/android/media/IMediaControllerCallback.aidl
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2014 The Android Open Source Project
+/*
+ * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,16 +14,12 @@
  * limitations under the License.
  */
 
-package android.media;
+package com.android.framework.multidexlegacyversionedtestapp;
 
-import android.os.Bundle;
+/* can go in secondary dex */
+public class Version {
 
-/**
- * @hide
- */
-oneway interface IMediaControllerCallback {
-    void onEvent(String event, in Bundle extras);
-    void onMetadataUpdate(in Bundle metadata);
-    void onPlaybackUpdate(int newState);
-    void onRouteChanged(in Bundle route);
-}
\ No newline at end of file
+    public static int getVersion() {
+        return 2;
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
new file mode 100644
index 0000000..945bfcc
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
@@ -0,0 +1,41 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v3
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
new file mode 100644
index 0000000..76c92dd
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.framework.multidexlegacyversionedtestapp"
+    android:versionCode="3"
+    android:versionName="3.0" >
+
+    <uses-sdk
+        android:minSdkVersion="9"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:name="android.support.multidex.MultiDexApplication"
+        android:allowBackup="true"
+        android:label="MultiDexLegacyVersionedTestApp_v3">
+        <activity
+            android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+            android:label="MultiDexLegacyVersionedTestApp_v3" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+                     android:label="Test for MultiDexLegacyVersionedTestApp_v3" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+    public static int getVersion() {
+        return Version.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+
+    public int getVersion() {
+        return ClassForMainDex.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..67aa478
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+    public MultiDexUpdateTest() {
+        super(MainActivity.class);
+    }
+
+    /**
+     * Tests that all classes of the application can be loaded. Verifies also that we load the
+     * correct version of {@link Version} ie the class is the secondary dex file.
+     */
+    public void testAllClassAvailable()
+    {
+        assertEquals(3, getActivity().getVersion());
+    }
+}
diff --git a/media/java/android/media/IMediaControllerCallback.aidl b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
similarity index 61%
copy from media/java/android/media/IMediaControllerCallback.aidl
copy to core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
index b54d0cf..1c8ef3b 100644
--- a/media/java/android/media/IMediaControllerCallback.aidl
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2014 The Android Open Source Project
+/*
+ * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,16 +14,12 @@
  * limitations under the License.
  */
 
-package android.media;
+package com.android.framework.multidexlegacyversionedtestapp;
 
-import android.os.Bundle;
+/* can go in secondary dex */
+public class Version {
 
-/**
- * @hide
- */
-oneway interface IMediaControllerCallback {
-    void onEvent(String event, in Bundle extras);
-    void onMetadataUpdate(in Bundle metadata);
-    void onPlaybackUpdate(int newState);
-    void onRouteChanged(in Bundle route);
-}
\ No newline at end of file
+    public static int getVersion() {
+        return 3;
+    }
+}
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index 0a2b50c..fa1bd8f 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -34,6 +34,7 @@
     private static final boolean IS_AUX = true;
     private static final boolean IS_DEFAULT = true;
     private static final boolean IS_AUTO = true;
+    private static final ArrayList<InputMethodSubtype> NO_SUBTYPE = null;
 
     @SmallTest
     public void testDefaultEnabledImesWithDefaultVoiceIme() throws Exception {
@@ -45,6 +46,7 @@
         imis.add(createNonDefaultDummyVoiceIme2());
         imis.add(createDefaultDummyEnUSKeyboardIme());
         imis.add(createNonDefaultDummyJaJPKeyboardIme());
+        imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
         final ArrayList<InputMethodInfo> enabledImis = InputMethodUtils.getDefaultEnabledImes(
                 context, true, imis);
         assertEquals(2, enabledImis.size());
@@ -69,6 +71,7 @@
         imis.add(createNonDefaultDummyVoiceIme2());
         imis.add(createDefaultDummyEnUSKeyboardIme());
         imis.add(createNonDefaultDummyJaJPKeyboardIme());
+        imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
         final ArrayList<InputMethodInfo> enabledImis = InputMethodUtils.getDefaultEnabledImes(
                 context, true, imis);
         assertEquals(3, enabledImis.size());
@@ -86,6 +89,55 @@
         }
     }
 
+    @SmallTest
+    public void testParcelable() throws Exception {
+        final ArrayList<InputMethodInfo> originalList = new ArrayList<InputMethodInfo>();
+        originalList.add(createNonDefaultAutoDummyVoiceIme0());
+        originalList.add(createNonDefaultAutoDummyVoiceIme1());
+        originalList.add(createNonDefaultDummyVoiceIme2());
+        originalList.add(createDefaultDummyEnUSKeyboardIme());
+        originalList.add(createNonDefaultDummyJaJPKeyboardIme());
+        originalList.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
+
+        final List<InputMethodInfo> clonedList = cloneViaParcel(originalList);
+        assertNotNull(clonedList);
+        final List<InputMethodInfo> clonedClonedList = cloneViaParcel(clonedList);
+        assertNotNull(clonedClonedList);
+        assertEquals(originalList, clonedList);
+        assertEquals(clonedList, clonedClonedList);
+        assertEquals(originalList.size(), clonedList.size());
+        assertEquals(clonedList.size(), clonedClonedList.size());
+        for (int imeIndex = 0; imeIndex < originalList.size(); ++imeIndex) {
+            verifyEquality(originalList.get(imeIndex), clonedList.get(imeIndex));
+            verifyEquality(clonedList.get(imeIndex), clonedClonedList.get(imeIndex));
+        }
+    }
+
+    private static List<InputMethodInfo> cloneViaParcel(final List<InputMethodInfo> list) {
+        Parcel p = null;
+        try {
+            p = Parcel.obtain();
+            p.writeTypedList(list);
+            p.setDataPosition(0);
+            return p.createTypedArrayList(InputMethodInfo.CREATOR);
+        } finally {
+            if (p != null) {
+                p.recycle();
+            }
+        }
+    }
+
+    private static void verifyEquality(InputMethodInfo expected, InputMethodInfo actual) {
+        assertEquals(expected, actual);
+        assertEquals(expected.getSubtypeCount(), actual.getSubtypeCount());
+        for (int subtypeIndex = 0; subtypeIndex < expected.getSubtypeCount(); ++subtypeIndex) {
+            final InputMethodSubtype expectedSubtype = expected.getSubtypeAt(subtypeIndex);
+            final InputMethodSubtype actualSubtype = actual.getSubtypeAt(subtypeIndex);
+            assertEquals(expectedSubtype, actualSubtype);
+            assertEquals(expectedSubtype.hashCode(), actualSubtype.hashCode());
+        }
+    }
+
     private static InputMethodInfo createDummyInputMethodInfo(String packageName, String name,
             CharSequence label, boolean isAuxIme, boolean isDefault,
             List<InputMethodSubtype> subtypes) {
@@ -155,4 +207,12 @@
         return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardIme", "dummy.keyboard1",
                 "DummyKeyboard1", !IS_AUX, !IS_DEFAULT, subtypes);
     }
+
+    // Although IMEs that have no subtype are considered to be deprecated, the Android framework
+    // must still be able to handle such IMEs as well as IMEs that have at least one subtype.
+    private static InputMethodInfo createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes() {
+        final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+        return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardImeWithoutSubtypes",
+                "dummy.keyboard2", "DummyKeyboard2", !IS_AUX, !IS_DEFAULT, NO_SUBTYPE);
+    }
 }
diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml
index 16e4c7c..549f061b 100644
--- a/data/fonts/system_fonts.xml
+++ b/data/fonts/system_fonts.xml
@@ -75,7 +75,6 @@
             <name>baskerville</name>
             <name>goudy</name>
             <name>fantasy</name>
-            <name>cursive</name>
             <name>ITC Stone Serif</name>
         </nameset>
         <fileset>
@@ -108,4 +107,32 @@
         </fileset>
     </family>
 
+    <family>
+        <nameset>
+            <name>casual</name>
+        </nameset>
+        <fileset>
+            <file>ComingSoon.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>cursive</name>
+        </nameset>
+        <fileset>
+            <file>DancingScript-Regular.ttf</file>
+            <file>DancingScript-Bold.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>sans-serif-smallcaps</name>
+        </nameset>
+        <fileset>
+            <file>CarroisGothicSC-Regular.ttf</file>
+        </fileset>
+    </family>
+
 </familyset>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index bc22416..bc793f1 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -27,21 +27,21 @@
 
 
 
-sdk.linux_download=android-sdk_r22.3-linux.tgz
-sdk.linux_bytes=100968558
-sdk.linux_checksum=6ae581a906d6420ad67176dff25a31cc
+sdk.linux_download=android-sdk_r22.6-linux.tgz
+sdk.linux_bytes=100992666
+sdk.linux_checksum=dde27b72715e52693c1ebc908742fc40
 
-sdk.mac_download=android-sdk_r22.3-macosx.zip
-sdk.mac_bytes=74893875
-sdk.mac_checksum=ecde88ca1f05955826697848fcb4a9e7
+sdk.mac_download=android-sdk_r22.6-macosx.zip
+sdk.mac_bytes=74547402
+sdk.mac_checksum=10c0e2ab65444c4911d69356ca2343f5
 
-sdk.win_download=android-sdk_r22.3-windows.zip
-sdk.win_bytes=108847452
-sdk.win_checksum=9f0fe8c8884d6aee2b298fee203c62dc
+sdk.win_download=android-sdk_r22.6-windows.zip
+sdk.win_bytes=108862292
+sdk.win_checksum=6faa487d328be352a456c53d9cbf0e3d
 
-sdk.win_installer=installer_r22.3-windows.exe
-sdk.win_installer_bytes=88845794
-sdk.win_installer_checksum=ad50c4dd9e23cee65a1ed740ff3345fa
+sdk.win_installer=installer_r22.6-windows.exe
+sdk.win_installer_bytes=88856450
+sdk.win_installer_checksum=6e5351b414bd554f3ac4c79f9dd4d213
 
 
 
@@ -363,8 +363,8 @@
 <div class="col-6 reqs" style="margin:0 0 15px 20px;display:none;">
 <h5>Eclipse IDE</h5>
     <ul>
-      <li><a href="http://eclipse.org/mobile/">Eclipse</a> 3.6.2 (Helios) or greater
-<p class="note"><strong>Note:</strong> Eclipse 3.5 (Galileo) is no longer
+      <li><a href="http://eclipse.org/mobile/">Eclipse</a> 3.7.2 (Indigo) or greater
+<p class="note"><strong>Note:</strong> Eclipse 3.6 (Helios) is no longer
 supported with the latest version of ADT.</p></li>
       <li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included
 in most Eclipse IDE packages) </li>
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 66c3034..42cb92c 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
 page.title=Installing the Eclipse Plugin
-adt.zip.version=22.3.0
-adt.zip.download=ADT-22.3.0.zip
-adt.zip.bytes=14493723
-adt.zip.checksum=0189080b23dfa0f866adafaaafcc34ab
+adt.zip.version=22.6.0
+adt.zip.download=ADT-22.6.0.zip
+adt.zip.bytes=14585211
+adt.zip.checksum=d95c6d8e678881f6c89f063b58d4162f
 
 @jd:body
 
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index 749808f..c3c83ef 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -77,6 +77,18 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>Build Tools, Revision 19.0.3</a> <em>(March 2014)</em>
+  </p>
+  <div class="toggle-content-toggleme">
+
+    <p>Fixed an issue with RenderScript support.</p>
+
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>Build Tools, Revision 19.0.2</a> <em>(February 2014)</em>
   </p>
   <div class="toggle-content-toggleme">
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index c584ae5..d711e44 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -53,10 +53,73 @@
 <p>For a summary of all known issues in ADT, see <a
 href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
-
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>ADT 22.6.0</a> <em>(March 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+<dl>
+  <dt>Dependencies:</dt>
+
+  <dd>
+    <ul>
+      <li>Java 1.6 or higher is required.</li>
+      <li>Eclipse Indigo (Version 3.7.2) or higher is required.</li>
+      <li>This version of ADT is designed for use with
+        <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.6</a>.
+        If you haven't already installed SDK Tools r22.6 into your SDK, use the
+        Android SDK Manager to do so.</li>
+    </ul>
+  </dd>
+
+  <dt>General Notes:</dt>
+  <dd>
+    <ul>
+      <li><p>Added support for Java 7 language features like multi-catch, try-with-resources,
+            and the diamond operator. These features require version 19 or higher
+            of the Build Tools. Try-with-resources requires <code>minSdkVersion</code>
+            19; the rest of the new language features require
+            <code>minSdkVersion</code> 8 or higher.</p>
+          <p>To use the new language features after installing ADT 22.6.0, ensure
+            that you run Eclipse on JDK 7 and change your application project settings
+            to use JDK 7.</p>
+      </li>
+      <li>Added new lint checks:
+        <ul>
+          <li>Security:
+            <ul>
+              <li>Look for code potentially affected by a <code>SecureRandom</code>
+                  vulnerability.</li>
+              <li>Check that calls to <code>checkPermission</code> use the return
+                  value.</li>
+            </ul>
+          </li>
+          <li>Check that production builds do not use mock location providers.</li>
+        </ul>
+      </li>
+      <li>Updated the New Project templates to include the
+          <a href="{@docRoot}tools/support-library/features.html#v7-appcompat">
+          v7 appcompat Support Library</a>.</li>
+      <li>Updated the Android tools libraries to include the rendering sandbox,
+          improvements for converting resource XML string declarations to layout
+          strings, and other updates.</li>
+      <li>Improved the Gradle export wizard. Note that the new importer in Android
+          Studio is the preferred way to migrate existing projects to Gradle.</li>
+      <li>Fixed a deadlock during startup.</li>
+      <li>Fixed an issue with RenderScript support. Using RenderScript support mode
+          now requires version 19.0.3 of the Build Tools.</li>
+    </ul>
+  </dd>
+
+</dl>
+</div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
       alt=""/>ADT 22.3.0</a> <em>(October 2013)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index c28b946..99f0b38 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -26,10 +26,92 @@
 href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
 
-
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 22.6</a> <em>(March 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 18 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+          designed for use with ADT 22.6.0 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.6.0.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li><p>The command line <code>lint</code> script (<code>tools\lint.bat</code> on
+            Windows platforms, <code>tools/lint</code> on other platforms) and the
+            <code>lint</code> target on <code>ant</code> builds fail with the following
+            error:</p>
+            <p><code>Exception in thread "main" java.lang.NoClassDefFoundError:
+            lombok/ast/AstVisitor</code></p>
+            <p>As a temporary workaround, rename the file
+              <code>tools\lib\lombok-ast-0.2.2.jar</code> to
+            <code>tools\lib\lombok-ast.jar</code>.
+            We will release an updated version of the tools with a fix for
+            this issue as soon as possible.</p>
+          </li>
+        <li>Added support for Java 7 language features like multi-catch, try-with-resources,
+            and the diamond operator. These features require version 19 or higher
+            of the Build Tools. Try-with-resources requires <code>minSdkVersion</code>
+            19; the rest of the new language features require
+            <code>minSdkVersion</code> 8 or higher.</li>
+        <li>Added new lint checks:
+          <ul>
+            <li>Security:
+              <ul>
+                <li>Look for code potentially affected by a <code>SecureRandom</code>
+                    vulnerability.</li>
+                <li>Check that calls to <code>checkPermission</code> use the return value.</li>
+              </ul>
+            </li>
+            <li>Check that production builds do not use mock location providers.</li>
+            <li>Look for manifest values that are overwritten by values from Gradle build 
+                scripts.</li>
+          </ul>
+        </li>
+        <li>Fixed a number of minor issues in the SDK and build system.</li>
+        <li>Emulator:
+          <ul>
+            <li>Fixed a problem with the emulator shutting down immediately for Android 1.5
+                on the Nexus One and Nexus S devices.
+                (<a href="http://b.android.com/64945">Issue 64945</a>)</li>
+            <li>Fixed a problem with port numbers longer than four digits.
+                (<a href="http://b.android.com/60024">Issue 60024</a>)</li>
+            <li>Fixed battery errors for the Nexus One and Nexus S devices.
+                (<a href="http://b.android.com/39959">Issue 39959</a>)</li>
+            <li>Fixed a problem with paths or arguments that contain
+                spaces on Windows platforms.
+                (<a href="http://b.android.com/18317">Issue 18317</a>)</li>
+            <li>Fixed a problem with long path values on Windows platforms.
+                (<a href="http://b.android.com/33336">Issue 33336</a>)</li>
+            <li>Fixed a problem with the {@code -snapshot-list} command line
+                option on 64-bit systems.
+                (<a href="http://b.android.com/34233">Issue 34233</a>)</li>
+          </ul>
+        </li>
+        <li>Fixed an issue with RenderScript support. Using RenderScript support mode 
+          now requires version 19.0.3 of the Build Tools.</li>
+      </ul>
+    </dd>
+    </dl>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 22.3</a> <em>(October 2013)</em>
   </p>
 
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index d6b73fd..7676143 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -400,7 +400,7 @@
          * No color information is stored.
          * With this configuration, each pixel requires 1 byte of memory.
          */
-        ALPHA_8     (2),
+        ALPHA_8     (1),
 
         /**
          * Each pixel is stored on 2 bytes and only the RGB channels are
@@ -416,7 +416,7 @@
          * This configuration may be useful when using opaque bitmaps
          * that do not require high color fidelity.
          */
-        RGB_565     (4),
+        RGB_565     (3),
 
         /**
          * Each pixel is stored on 2 bytes. The three RGB color channels
@@ -438,7 +438,7 @@
          *             it is advised to use {@link #ARGB_8888} instead.
          */
         @Deprecated
-        ARGB_4444   (5),
+        ARGB_4444   (4),
 
         /**
          * Each pixel is stored on 4 bytes. Each channel (RGB and alpha
@@ -448,13 +448,13 @@
          * This configuration is very flexible and offers the best
          * quality. It should be used whenever possible.
          */
-        ARGB_8888   (6);
+        ARGB_8888   (5);
 
         final int nativeInt;
 
         @SuppressWarnings({"deprecation"})
         private static Config sConfigs[] = {
-            null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
+            null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
         };
         
         Config(int ni) {
diff --git a/graphics/java/android/graphics/LayerRasterizer.java b/graphics/java/android/graphics/LayerRasterizer.java
index dc307c6..5b356089 100644
--- a/graphics/java/android/graphics/LayerRasterizer.java
+++ b/graphics/java/android/graphics/LayerRasterizer.java
@@ -21,11 +21,11 @@
         native_instance = nativeConstructor();
     }
     
-	/**	Add a new layer (above any previous layers) to the rasterizer.
-		The layer will extract those fields that affect the mask from
-		the specified paint, but will not retain a reference to the paint
-		object itself, so it may be reused without danger of side-effects.
-	*/
+    /** Add a new layer (above any previous layers) to the rasterizer.
+        The layer will extract those fields that affect the mask from
+        the specified paint, but will not retain a reference to the paint
+        object itself, so it may be reused without danger of side-effects.
+    */
     public void addLayer(Paint paint, float dx, float dy) {
         nativeAddLayer(native_instance, paint.mNativePaint, dx, dy);
     }
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 9ad3e49..0eae67c 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -38,7 +38,7 @@
 
     private TileMode mTileMode;
 
-	/**	Create a shader that draws a linear gradient along a line.
+    /** Create a shader that draws a linear gradient along a line.
         @param x0           The x-coordinate for the start of the gradient line
         @param y0           The y-coordinate for the start of the gradient line
         @param x1           The x-coordinate for the end of the gradient line
@@ -48,8 +48,8 @@
                             each corresponding color in the colors array. If this is null,
                             the the colors are distributed evenly along the gradient line.
         @param  tile        The Shader tiling mode
-	*/
-	public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
+    */
+    public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
             TileMode tile) {
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
@@ -70,7 +70,7 @@
                 tile.nativeInt);
     }
 
-	/**	Create a shader that draws a linear gradient along a line.
+    /** Create a shader that draws a linear gradient along a line.
         @param x0       The x-coordinate for the start of the gradient line
         @param y0       The y-coordinate for the start of the gradient line
         @param x1       The x-coordinate for the end of the gradient line
@@ -78,8 +78,8 @@
         @param  color0  The color at the start of the gradient line.
         @param  color1  The color at the end of the gradient line.
         @param  tile    The Shader tiling mode
-	*/
-	public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
+    */
+    public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
             TileMode tile) {
         mType = TYPE_COLOR_START_AND_COLOR_END;
         mX0 = x0;
@@ -118,7 +118,7 @@
 
     private native long nativeCreate1(float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
-	private native long nativeCreate2(float x0, float y0, float x1, float y1,
+    private native long nativeCreate2(float x0, float y0, float x1, float y1,
             int color0, int color1, int tileMode);
     private native long nativePostCreate1(long native_shader, float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index f10e5d6..c00c612 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -37,17 +37,17 @@
 
     private TileMode mTileMode;
 
-	/**	Create a shader that draws a radial gradient given the center and radius.
+    /** Create a shader that draws a radial gradient given the center and radius.
         @param x        The x-coordinate of the center of the radius
         @param y        The y-coordinate of the center of the radius
-		@param radius   Must be positive. The radius of the circle for this gradient
+        @param radius   Must be positive. The radius of the circle for this gradient
         @param colors   The colors to be distributed between the center and edge of the circle
         @param positions May be NULL. The relative position of
                         each corresponding color in the colors array. If this is NULL,
                         the the colors are distributed evenly between the center and edge of the circle.
         @param  tile    The Shader tiling mode
-	*/
-	public RadialGradient(float x, float y, float radius,
+    */
+    public RadialGradient(float x, float y, float radius,
                           int colors[], float positions[], TileMode tile) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
@@ -70,15 +70,15 @@
                 tile.nativeInt);
     }
 
-	/**	Create a shader that draws a radial gradient given the center and radius.
+    /** Create a shader that draws a radial gradient given the center and radius.
         @param x        The x-coordinate of the center of the radius
         @param y        The y-coordinate of the center of the radius
-		@param radius   Must be positive. The radius of the circle for this gradient
+        @param radius   Must be positive. The radius of the circle for this gradient
         @param color0   The color at the center of the circle.
         @param color1   The color at the edge of the circle.
         @param tile     The Shader tiling mode
-	*/
-	public RadialGradient(float x, float y, float radius,
+    */
+    public RadialGradient(float x, float y, float radius,
                           int color0, int color1, TileMode tile) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
@@ -119,7 +119,7 @@
 
     private static native long nativeCreate1(float x, float y, float radius,
             int colors[], float positions[], int tileMode);
-	private static native long nativeCreate2(float x, float y, float radius,
+    private static native long nativeCreate2(float x, float y, float radius,
             int color0, int color1, int tileMode);
 
     private static native long nativePostCreate1(long native_shader, float x, float y, float radius,
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 2f4196a..fe08f4b 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -27,10 +27,8 @@
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.GradientDrawable.GradientState;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.Xfermode;
@@ -558,6 +556,11 @@
         invalidateSelf();
     }
 
+    @Override
+    public ColorFilter getColorFilter() {
+        return mBitmapState.mPaint.getColorFilter();
+    }
+
     /**
      * Specifies a tint for this drawable.
      * <p>
@@ -568,31 +571,63 @@
      *            clear the tint
      */
     public void setTint(ColorStateList tint) {
-        mBitmapState.mTint = tint;
-        if (mTintFilter == null) {
-            if (tint != null) {
-                final int color = tint.getColorForState(getState(), 0);
-                mTintFilter = new PorterDuffColorFilter(color, mBitmapState.mTintMode);
-            }
-        } else {
-            if (tint == null) {
-                mTintFilter = null;
-            }
+        if (mBitmapState.mTint != tint) {
+            mBitmapState.mTint = tint;
+            updateTintFilter();
+            invalidateSelf();
         }
-        invalidateSelf();
+    }
+
+    /**
+     * Returns the tint color for this drawable.
+     *
+     * @return Color state list to use for tinting this drawable, or null if
+     *         none set
+     */
+    public ColorStateList getTint() {
+        return mBitmapState.mTint;
     }
 
     /**
      * Specifies the blending mode used to apply tint.
      *
      * @param tintMode A Porter-Duff blending mode
+     * @hide Pending finalization of supported Modes
      */
     public void setTintMode(Mode tintMode) {
-        mBitmapState.mTintMode = tintMode;
-        if (mTintFilter != null) {
-            mTintFilter.setMode(tintMode);
+        if (mBitmapState.mTintMode != tintMode) {
+            mBitmapState.mTintMode = tintMode;
+            updateTintFilter();
+            invalidateSelf();
         }
-        invalidateSelf();
+    }
+
+    /**
+     * Returns the tint mode for this drawable, or {@code null} if none set.
+     *
+     * @return the tint mode for this drawable, or {@code null} if none set
+     * @hide
+     */
+    public Mode getTintMode() {
+        return mBitmapState.mTintMode;
+    }
+
+    /**
+     * Ensures the tint filter is consistent with the current tint color and
+     * mode.
+     */
+    private void updateTintFilter() {
+        final ColorStateList tint = mBitmapState.mTint;
+        final Mode tintMode = mBitmapState.mTintMode;
+        if (tint != null && tintMode != null) {
+            if (mTintFilter == null) {
+                mTintFilter = new PorterDuffColorFilter(0, tintMode);
+            } else {
+                mTintFilter.setMode(tintMode);
+            }
+        } else {
+            mTintFilter = null;
+        }
     }
 
     /**
@@ -730,7 +765,7 @@
     final static class BitmapState extends ConstantState {
         Bitmap mBitmap;
         ColorStateList mTint;
-        Mode mTintMode;
+        Mode mTintMode = Mode.SRC_IN;
         int mChangingConfigurations;
         int mGravity = Gravity.FILL;
         Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS);
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index a9cf115..84211ef 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -454,12 +454,6 @@
     }
 
     /**
-     * Specify an optional color filter for the drawable. Pass null to remove
-     * any existing color filter.
-     */
-    public abstract void setColorFilter(ColorFilter cf);
-
-    /**
      * @hide Consider for future API inclusion
      */
     public void setXfermode(Xfermode mode) {
@@ -469,6 +463,15 @@
     }
 
     /**
+     * Specify an optional color filter for the drawable. Pass {@code null} to
+     * remove any existing color filter.
+     *
+     * @param cf the color filter to apply, or {@code null} to remove the
+     *            existing color filter
+     */
+    public abstract void setColorFilter(ColorFilter cf);
+
+    /**
      * Specify a color and Porter-Duff mode to be the color filter for this
      * drawable.
      */
@@ -477,6 +480,15 @@
     }
 
     /**
+     * Returns the current color filter, or {@code null} if none set.
+     *
+     * @return the current color filter, or {@code null} if none set
+     */
+    public ColorFilter getColorFilter() {
+        return null;
+    }
+
+    /**
      * Removes the color filter for this drawable.
      */
     public void clearColorFilter() {
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index aab1fd9..44584a7 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -27,11 +27,10 @@
 import android.graphics.NinePatch;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.drawable.BitmapDrawable.BitmapState;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.LayoutDirection;
@@ -327,31 +326,53 @@
      *            clear the tint
      */
     public void setTint(ColorStateList tint) {
-        mNinePatchState.mTint = tint;
-        if (mTintFilter == null) {
-            if (tint != null) {
-                final int color = tint.getColorForState(getState(), 0);
-                mTintFilter = new PorterDuffColorFilter(color, mNinePatchState.mTintMode);
-            }
-        } else {
-            if (tint == null) {
-                mTintFilter = null;
-            }
+        if (mNinePatchState.mTint != tint) {
+            mNinePatchState.mTint = tint;
+            updateTintFilter();
+            invalidateSelf();
         }
-        invalidateSelf();
+    }
+
+    /**
+     * Returns the tint color for this drawable.
+     *
+     * @return Color state list to use for tinting this drawable, or null if
+     *         none set
+     */
+    public ColorStateList getTint() {
+        return mNinePatchState.mTint;
     }
 
     /**
      * Specifies the blending mode used to apply tint.
      *
      * @param tintMode A Porter-Duff blending mode
+     * @hide Pending finalization of supported Modes
      */
     public void setTintMode(Mode tintMode) {
-        mNinePatchState.mTintMode = tintMode;
-        if (mTintFilter != null) {
-            mTintFilter.setMode(tintMode);
+        if (mNinePatchState.mTintMode != tintMode) {
+            mNinePatchState.mTintMode = tintMode;
+            updateTintFilter();
+            invalidateSelf();
         }
-        invalidateSelf();
+    }
+
+    /**
+     * Ensures the tint filter is consistent with the current tint color and
+     * mode.
+     */
+    private void updateTintFilter() {
+        final ColorStateList tint = mNinePatchState.mTint;
+        final Mode tintMode = mNinePatchState.mTintMode;
+        if (tint != null && tintMode != null) {
+            if (mTintFilter == null) {
+                mTintFilter = new PorterDuffColorFilter(0, tintMode);
+            } else {
+                mTintFilter.setMode(tintMode);
+            }
+        } else {
+            mTintFilter = null;
+        }
     }
 
     @Override
@@ -543,7 +564,7 @@
     final static class NinePatchState extends ConstantState {
         NinePatch mNinePatch;
         ColorStateList mTint;
-        Mode mTintMode;
+        Mode mTintMode = Mode.SRC_IN;
         Rect mPadding;
         Insets mOpticalInsets;
         boolean mDither;
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 93f2dc60..16de9f3 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -16,10 +16,18 @@
 
 package android.graphics.drawable;
 
-import android.graphics.*;
-import android.graphics.drawable.shapes.Shape;
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.drawable.shapes.Shape;
 import android.util.AttributeSet;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -28,22 +36,24 @@
 import java.io.IOException;
 
 /**
- * A Drawable object that draws primitive shapes. 
- * A ShapeDrawable takes a {@link android.graphics.drawable.shapes.Shape}
- * object and manages its presence on the screen. If no Shape is given, then
- * the ShapeDrawable will default to a 
- * {@link android.graphics.drawable.shapes.RectShape}.
- *
- * <p>This object can be defined in an XML file with the <code>&lt;shape></code> element.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about how to use ShapeDrawable, read the
- * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable">
- * Canvas and Drawables</a> document. For more information about defining a ShapeDrawable in
- * XML, read the
- * <a href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
- * document.</p></div>
+ * A Drawable object that draws primitive shapes. A ShapeDrawable takes a
+ * {@link android.graphics.drawable.shapes.Shape} object and manages its
+ * presence on the screen. If no Shape is given, then the ShapeDrawable will
+ * default to a {@link android.graphics.drawable.shapes.RectShape}.
+ * <p>
+ * This object can be defined in an XML file with the <code>&lt;shape></code>
+ * element.
+ * </p>
+ * <div class="special reference"> <h3>Developer Guides</h3>
+ * <p>
+ * For more information about how to use ShapeDrawable, read the <a
+ * href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable">
+ * Canvas and Drawables</a> document. For more information about defining a
+ * ShapeDrawable in XML, read the <a href="{@docRoot}
+ * guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
+ * document.
+ * </p>
+ * </div>
  *
  * @attr ref android.R.styleable#ShapeDrawablePadding_left
  * @attr ref android.R.styleable#ShapeDrawablePadding_top
@@ -55,6 +65,7 @@
  */
 public class ShapeDrawable extends Drawable {
     private ShapeState mShapeState;
+    private PorterDuffColorFilter mTintFilter;
     private boolean mMutated;
 
     /**
@@ -63,20 +74,25 @@
     public ShapeDrawable() {
         this((ShapeState) null);
     }
-    
+
     /**
      * Creates a ShapeDrawable with a specified Shape.
-     * 
+     *
      * @param s the Shape that this ShapeDrawable should be
      */
     public ShapeDrawable(Shape s) {
         this((ShapeState) null);
-        
+
         mShapeState.mShape = s;
     }
-    
+
     private ShapeDrawable(ShapeState state) {
         mShapeState = new ShapeState(state);
+
+        if (state != null && state.mTint != null) {
+            final int color = state.mTint.getColorForState(getState(), 0);
+            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
+        }
     }
 
     /**
@@ -85,7 +101,7 @@
     public Shape getShape() {
         return mShapeState.mShape;
     }
-    
+
     /**
      * Sets the Shape of this ShapeDrawable.
      */
@@ -93,19 +109,19 @@
         mShapeState.mShape = s;
         updateShape();
     }
-    
+
     /**
-     * Sets a ShaderFactory to which requests for a 
+     * Sets a ShaderFactory to which requests for a
      * {@link android.graphics.Shader} object will be made.
-     * 
+     *
      * @param fact an instance of your ShaderFactory implementation
      */
     public void setShaderFactory(ShaderFactory fact) {
         mShapeState.mShaderFactory = fact;
     }
-    
+
     /**
-     * Returns the ShaderFactory used by this ShapeDrawable for requesting a 
+     * Returns the ShaderFactory used by this ShapeDrawable for requesting a
      * {@link android.graphics.Shader}.
      */
     public ShaderFactory getShaderFactory() {
@@ -118,14 +134,14 @@
     public Paint getPaint() {
         return mShapeState.mPaint;
     }
-    
+
     /**
      * Sets padding for the shape.
-     * 
-     * @param left    padding for the left side (in pixels)
-     * @param top     padding for the top (in pixels)
-     * @param right   padding for the right side (in pixels)
-     * @param bottom  padding for the bottom (in pixels)
+     *
+     * @param left padding for the left side (in pixels)
+     * @param top padding for the top (in pixels)
+     * @param right padding for the right side (in pixels)
+     * @param bottom padding for the bottom (in pixels)
      */
     public void setPadding(int left, int top, int right, int bottom) {
         if ((left | top | right | bottom) == 0) {
@@ -138,10 +154,10 @@
         }
         invalidateSelf();
     }
-    
+
     /**
-     * Sets padding for this shape, defined by a Rect object.
-     * Define the padding in the Rect object as: left, top, right, bottom.
+     * Sets padding for this shape, defined by a Rect object. Define the padding
+     * in the Rect object as: left, top, right, bottom.
      */
     public void setPadding(Rect padding) {
         if (padding == null) {
@@ -154,37 +170,37 @@
         }
         invalidateSelf();
     }
-    
+
     /**
      * Sets the intrinsic (default) width for this shape.
-     * 
+     *
      * @param width the intrinsic width (in pixels)
      */
     public void setIntrinsicWidth(int width) {
         mShapeState.mIntrinsicWidth = width;
         invalidateSelf();
     }
-    
+
     /**
      * Sets the intrinsic (default) height for this shape.
-     * 
+     *
      * @param height the intrinsic height (in pixels)
      */
     public void setIntrinsicHeight(int height) {
         mShapeState.mIntrinsicHeight = height;
         invalidateSelf();
     }
-    
+
     @Override
     public int getIntrinsicWidth() {
         return mShapeState.mIntrinsicWidth;
     }
-    
+
     @Override
     public int getIntrinsicHeight() {
         return mShapeState.mIntrinsicHeight;
     }
-    
+
     @Override
     public boolean getPadding(Rect padding) {
         if (mShapeState.mPadding != null) {
@@ -196,14 +212,14 @@
     }
 
     private static int modulateAlpha(int paintAlpha, int alpha) {
-        int scale = alpha + (alpha >>> 7);  // convert to 0..256
+        int scale = alpha + (alpha >>> 7); // convert to 0..256
         return paintAlpha * scale >>> 8;
     }
 
     /**
-     * Called from the drawable's draw() method after the canvas has been set
-     * to draw the shape at (0,0). Subclasses can override for special effects
-     * such as multiple layers, stroking, etc.
+     * Called from the drawable's draw() method after the canvas has been set to
+     * draw the shape at (0,0). Subclasses can override for special effects such
+     * as multiple layers, stroking, etc.
      */
     protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
         shape.draw(canvas, paint);
@@ -211,23 +227,37 @@
 
     @Override
     public void draw(Canvas canvas) {
-        Rect r = getBounds();
-        Paint paint = mShapeState.mPaint;
+        final Rect r = getBounds();
+        final ShapeState state = mShapeState;
+        final Paint paint = state.mPaint;
 
-        int prevAlpha = paint.getAlpha();
-        paint.setAlpha(modulateAlpha(prevAlpha, mShapeState.mAlpha));
+        final int prevAlpha = paint.getAlpha();
+        paint.setAlpha(modulateAlpha(prevAlpha, state.mAlpha));
 
         // only draw shape if it may affect output
         if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadow) {
-            if (mShapeState.mShape != null) {
-                // need the save both for the translate, and for the (unknown) Shape
-                int count = canvas.save();
+            final boolean clearColorFilter;
+            if (mTintFilter != null && paint.getColorFilter() == null) {
+                paint.setColorFilter(mTintFilter);
+                clearColorFilter = true;
+            } else {
+                clearColorFilter = false;
+            }
+
+            if (state.mShape != null) {
+                // need the save both for the translate, and for the (unknown)
+                // Shape
+                final int count = canvas.save();
                 canvas.translate(r.left, r.top);
-                onDraw(mShapeState.mShape, canvas, paint);
+                onDraw(state.mShape, canvas, paint);
                 canvas.restoreToCount(count);
             } else {
                 canvas.drawRect(r, paint);
             }
+
+            if (clearColorFilter) {
+                paint.setColorFilter(null);
+            }
         }
 
         // restore
@@ -239,16 +269,17 @@
         return super.getChangingConfigurations()
                 | mShapeState.mChangingConfigurations;
     }
-    
+
     /**
      * Set the alpha level for this drawable [0..255]. Note that this drawable
      * also has a color in its paint, which has an alpha as well. These two
      * values are automatically combined during drawing. Thus if the color's
      * alpha is 75% (i.e. 192) and the drawable's alpha is 50% (i.e. 128), then
-     * the combined alpha that will be used during drawing will be 37.5%
-     * (i.e. 96).
+     * the combined alpha that will be used during drawing will be 37.5% (i.e.
+     * 96).
      */
-    @Override public void setAlpha(int alpha) {
+    @Override
+    public void setAlpha(int alpha) {
         mShapeState.mAlpha = alpha;
         invalidateSelf();
     }
@@ -258,12 +289,81 @@
         return mShapeState.mAlpha;
     }
 
+    /**
+     * Specifies a tint for this drawable.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tint Color state list to use for tinting this drawable, or null to
+     *            clear the tint
+     */
+    public void setTint(ColorStateList tint) {
+        if (mShapeState.mTint != tint) {
+            mShapeState.mTint = tint;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Returns the tint color for this drawable.
+     *
+     * @return Color state list to use for tinting this drawable, or null if
+     *         none set
+     */
+    public ColorStateList getTint() {
+        return mShapeState.mTint;
+    }
+
+    /**
+     * Specifies the blending mode used to apply tint.
+     *
+     * @param tintMode A Porter-Duff blending mode
+     * @hide Pending finalization of supported Modes
+     */
+    public void setTintMode(Mode tintMode) {
+        if (mShapeState.mTintMode != tintMode) {
+            mShapeState.mTintMode = tintMode;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Ensures the tint filter is consistent with the current tint color and
+     * mode.
+     */
+    private void updateTintFilter() {
+        final ColorStateList tint = mShapeState.mTint;
+        final Mode tintMode = mShapeState.mTintMode;
+        if (tint != null && tintMode != null) {
+            if (mTintFilter == null) {
+                mTintFilter = new PorterDuffColorFilter(0, tintMode);
+            } else {
+                mTintFilter.setMode(tintMode);
+            }
+        } else {
+            mTintFilter = null;
+        }
+    }
+
+    /**
+     * Returns the blending mode used to apply tint.
+     *
+     * @return The Porter-Duff blending mode used to apply tint.
+     * @hide Pending finalization of supported Modes
+     */
+    public Mode getTintMode() {
+        return mShapeState.mTintMode;
+    }
+
     @Override
     public void setColorFilter(ColorFilter cf) {
         mShapeState.mPaint.setColorFilter(cf);
         invalidateSelf();
     }
-    
+
     @Override
     public int getOpacity() {
         if (mShapeState.mShape == null) {
@@ -294,9 +394,31 @@
         updateShape();
     }
 
+    @Override
+    protected boolean onStateChange(int[] stateSet) {
+        final ColorStateList tint = mShapeState.mTint;
+        if (tint != null) {
+            final int newColor = tint.getColorForState(stateSet, 0);
+            final int oldColor = mTintFilter.getColor();
+            if (oldColor != newColor) {
+                mTintFilter.setColor(newColor);
+                invalidateSelf();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isStateful() {
+        final ShapeState s = mShapeState;
+        return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
+    }
+
     /**
-     * Subclasses override this to parse custom subelements.
-     * If you handle it, return true, else return <em>super.inflateTag(...)</em>.
+     * Subclasses override this to parse custom subelements. If you handle it,
+     * return true, else return <em>super.inflateTag(...)</em>.
      */
     protected boolean inflateTag(String name, Resources r, XmlPullParser parser,
             AttributeSet attrs) {
@@ -322,7 +444,7 @@
 
     @Override
     public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
-                        throws XmlPullParserException, IOException {
+            throws XmlPullParserException, IOException {
         super.inflate(r, parser, attrs);
 
         TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.ShapeDrawable);
@@ -343,12 +465,12 @@
 
         int type;
         final int outerDepth = parser.getDepth();
-        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-               && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
             if (type != XmlPullParser.START_TAG) {
                 continue;
             }
-            
+
             final String name = parser.getName();
             // call our subclass
             if (!inflateTag(name, r, parser, attrs)) {
@@ -371,7 +493,7 @@
         }
         invalidateSelf();
     }
-    
+
     @Override
     public ConstantState getConstantState() {
         mShapeState.mChangingConfigurations = getChangingConfigurations();
@@ -408,16 +530,20 @@
         int mChangingConfigurations;
         Paint mPaint;
         Shape mShape;
+        ColorStateList mTint;
+        Mode mTintMode = Mode.SRC_IN;
         Rect mPadding;
         int mIntrinsicWidth;
         int mIntrinsicHeight;
         int mAlpha = 255;
         ShaderFactory mShaderFactory;
-        
+
         ShapeState(ShapeState orig) {
             if (orig != null) {
                 mPaint = orig.mPaint;
                 mShape = orig.mShape;
+                mTint = orig.mTint;
+                mTintMode = orig.mTintMode;
                 mPadding = orig.mPadding;
                 mIntrinsicWidth = orig.mIntrinsicWidth;
                 mIntrinsicHeight = orig.mIntrinsicHeight;
@@ -427,48 +553,45 @@
                 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
             }
         }
-        
+
         @Override
         public Drawable newDrawable() {
             return new ShapeDrawable(this);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new ShapeDrawable(this);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
         }
     }
-    
+
     /**
      * Base class defines a factory object that is called each time the drawable
      * is resized (has a new width or height). Its resize() method returns a
-     * corresponding shader, or null.
-     * Implement this class if you'd like your ShapeDrawable to use a special
-     * {@link android.graphics.Shader}, such as a 
-     * {@link android.graphics.LinearGradient}. 
-     * 
+     * corresponding shader, or null. Implement this class if you'd like your
+     * ShapeDrawable to use a special {@link android.graphics.Shader}, such as a
+     * {@link android.graphics.LinearGradient}.
      */
     public static abstract class ShaderFactory {
         /**
-         * Returns the Shader to be drawn when a Drawable is drawn.
-         * The dimensions of the Drawable are passed because they may be needed
-         * to adjust how the Shader is configured for drawing.
-         * This is called by ShapeDrawable.setShape().
-         * 
-         * @param width  the width of the Drawable being drawn
+         * Returns the Shader to be drawn when a Drawable is drawn. The
+         * dimensions of the Drawable are passed because they may be needed to
+         * adjust how the Shader is configured for drawing. This is called by
+         * ShapeDrawable.setShape().
+         *
+         * @param width the width of the Drawable being drawn
          * @param height the heigh of the Drawable being drawn
-         * @return       the Shader to be drawn
+         * @return the Shader to be drawn
          */
         public abstract Shader resize(int width, int height);
     }
-    
+
     // other subclass could wack the Shader's localmatrix based on the
     // resize params (e.g. scaletofit, etc.). This could be used to scale
     // a bitmap to fill the bounds without needing any other special casing.
 }
-
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
index b8d3f48..302fbf6 100644
--- a/libs/androidfw/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -1083,7 +1083,7 @@
     }
 
     if (readSnapshot.size() != 4) {
-        fprintf(stderr, "readSnapshot should be length 4 is %d\n", readSnapshot.size());
+        fprintf(stderr, "readSnapshot should be length 4 is %zu\n", readSnapshot.size());
         return 1;
     }
 
@@ -1095,8 +1095,8 @@
         if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
                 || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
                 || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
-            fprintf(stderr, "state %d expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n"
-                            "          actual={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n", i,
+            fprintf(stderr, "state %zu expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n"
+                            "          actual={%d/%d, 0x%08x, %04o, 0x%08x, %3zu} '%s'\n", i,
                     states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
                     states[i].crc32, name.length(), filenames[i].string(),
                     state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
@@ -1230,7 +1230,7 @@
         goto finished;
     }
     if ((int)actualSize != bufSize) {
-        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
+        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08zx\n", bufSize,
                 actualSize);
         err = EINVAL;
         goto finished;
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 1f5d26c..4935b34 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -21,6 +21,7 @@
 #include <utils/Vector.h>
 
 #include "AmbientShadow.h"
+#include "ShadowTessellator.h"
 #include "Vertex.h"
 
 namespace android {
@@ -34,9 +35,7 @@
  *                  array.
  * @param vertexCount The length of caster's polygon in terms of number of
  *                    vertices.
- * @param rays The number of rays shooting out from the centroid.
- * @param layers The number of rings outside the polygon.
- * @param strength The darkness of the shadow, the higher, the darker.
+ * @param centroid3d The centroid of the shadow caster.
  * @param heightFactor The factor showing the higher the object, the lighter the
  *                     shadow.
  * @param geomFactor The factor scaling the geometry expansion along the normal.
@@ -45,21 +44,18 @@
  *               triangle strips mode.
  */
 void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount,
-        int rays, int layers, float strength, float heightFactor, float geomFactor,
+        const Vector3& centroid3d, float heightFactor, float geomFactor,
         VertexBuffer& shadowVertexBuffer) {
-
+    const int rays = SHADOW_RAY_COUNT;
+    const int layers = SHADOW_LAYER_COUNT;
     // Validate the inputs.
-    if (strength <= 0 || heightFactor <= 0 || layers <= 0 || rays <= 0
+    if (vertexCount < 3 || heightFactor <= 0 || layers <= 0 || rays <= 0
         || geomFactor <= 0) {
 #if DEBUG_SHADOW
         ALOGE("Invalid input for createAmbientShadow(), early return!");
 #endif
         return;
     }
-    int rings = layers + 1;
-    int size = rays * rings;
-    Vector2 centroid;
-    calculatePolygonCentroid(vertices, vertexCount, centroid);
 
     Vector<Vector2> dir; // TODO: use C++11 unique_ptr
     dir.setCapacity(rays);
@@ -75,7 +71,7 @@
         int edgeIndex;
         float edgeFraction;
         float rayDistance;
-        calculateIntersection(vertices, vertexCount, centroid, dir[i], edgeIndex,
+        calculateIntersection(vertices, vertexCount, centroid3d, dir[i], edgeIndex,
                 edgeFraction, rayDistance);
         rayDist[i] = rayDistance;
         if (edgeIndex < 0 || edgeIndex >= vertexCount) {
@@ -91,8 +87,7 @@
 
     // The output buffer length basically is roughly rays * layers, but since we
     // need triangle strips, so we need to duplicate vertices to accomplish that.
-    const int shadowVertexCount = (2 + rays + ((layers) * 2 * (rays + 1)));
-    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(shadowVertexCount);
+    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
 
     // Calculate the vertex of the shadows.
     //
@@ -101,110 +96,45 @@
     // calculate the normal N, which should be perpendicular to the edge of the
     // polygon (represented by the neighbor intersection points) .
     // Shadow's vertices will be generated as : P + N * scale.
-    int currentIndex = 0;
-    for (int r = 0; r < layers; r++) {
-        int firstInLayer = currentIndex;
-        for (int i = 0; i < rays; i++) {
+    int currentVertexIndex = 0;
+    for (int layerIndex = 0; layerIndex <= layers; layerIndex++) {
+        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
 
             Vector2 normal(1.0f, 0.0f);
-            calculateNormal(rays, i, dir.array(), rayDist, normal);
+            calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
 
-            float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor);
+            float opacity = 1.0 / (1 + rayHeight[rayIndex] / heightFactor);
 
             // The vertex should be start from rayDist[i] then scale the
             // normalizeNormal!
-            Vector2 intersection = dir[i] * rayDist[i] + centroid;
+            Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
+                    Vector2(centroid3d.x, centroid3d.y);
 
-            // Use 2 rings' vertices to complete one layer's strip
-            for (int j = r; j < (r + 2); j++) {
-                float jf = j / (float)(rings - 1);
-
-                float expansionDist = rayHeight[i] / heightFactor * geomFactor * jf;
-                AlphaVertex::set(&shadowVertices[currentIndex],
-                        intersection.x + normal.x * expansionDist,
-                        intersection.y + normal.y * expansionDist,
-                        (1 - jf) * opacity);
-                currentIndex++;
-            }
+            float layerRatio = layerIndex / (float)(layers);
+            // The higher the intersection is, the further the ambient shadow expanded.
+            float expansionDist = rayHeight[rayIndex] / heightFactor *
+                    geomFactor * (1 - layerRatio);
+            AlphaVertex::set(&shadowVertices[currentVertexIndex++],
+                    intersection.x + normal.x * expansionDist,
+                    intersection.y + normal.y * expansionDist,
+                    layerRatio * opacity);
         }
 
-        // From one layer to the next, we need to duplicate the vertex to
-        // continue as a single strip.
-        shadowVertices[currentIndex] = shadowVertices[firstInLayer];
-        currentIndex++;
-        shadowVertices[currentIndex] = shadowVertices[firstInLayer + 1];
-        currentIndex++;
     }
+    float centroidAlpha = 1.0 / (1 + centroid3d.z / heightFactor);
+    AlphaVertex::set(&shadowVertices[currentVertexIndex++],
+            centroid3d.x, centroid3d.y, centroidAlpha);
 
-    // After all rings are done, we need to jump into the polygon.
-    // In order to keep everything in a strip, we need to duplicate the last one
-    // of the rings and the first one inside the polygon.
-    int lastInRings = currentIndex - 1;
-    shadowVertices[currentIndex] = shadowVertices[lastInRings];
-    currentIndex++;
-
-    // We skip one and fill it back after we finish the internal triangles.
-    currentIndex++;
-    int firstInternal = currentIndex;
-
-    // Combine the internal area of the polygon into a triangle strip, too.
-    // The basic idea is zig zag between the intersection points.
-    // 0 -> (n - 1) -> 1 -> (n - 2) ...
-    for (int k = 0; k < rays; k++) {
-        int  i = k / 2;
-        if ((k & 1) == 1) { // traverse the inside in a zig zag pattern for strips
-            i = rays - i - 1;
-        }
-        float cast = rayDist[i] * (1 + rayHeight[i] / heightFactor);
-        float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor);
-        float t = rayDist[i];
-
-        AlphaVertex::set(&shadowVertices[currentIndex], dir[i].x * t + centroid.x,
-                dir[i].y * t + centroid.y, opacity);
-        currentIndex++;
-    }
-
-    currentIndex = firstInternal - 1;
-    shadowVertices[currentIndex] = shadowVertices[firstInternal];
-}
-
-/**
- * Calculate the centroid of a given polygon.
- *
- * @param vertices The shadow caster's polygon, which is represented in a
- *                 straight Vector3 array.
- * @param vertexCount The length of caster's polygon in terms of number of vertices.
- *
- * @param centroid Return the centroid of the polygon.
- */
-void AmbientShadow::calculatePolygonCentroid(const Vector3* vertices, int vertexCount,
-        Vector2& centroid) {
-    float sumx = 0;
-    float sumy = 0;
-    int p1 = vertexCount - 1;
-    float area = 0;
-    for (int p2 = 0; p2 < vertexCount; p2++) {
-        float x1 = vertices[p1].x;
-        float y1 = vertices[p1].y;
-        float x2 = vertices[p2].x;
-        float y2 = vertices[p2].y;
-        float a = (x1 * y2 - x2 * y1);
-        sumx += (x1 + x2) * a;
-        sumy += (y1 + y2) * a;
-        area += a;
-        p1 = p2;
-    }
-
-    if (area == 0) {
 #if DEBUG_SHADOW
-        ALOGE("Area is 0!");
-#endif
-        centroid.x = vertices[0].x;
-        centroid.y = vertices[0].y;
-    } else {
-        centroid.x = sumx / (3 * area);
-        centroid.y = sumy / (3 * area);
+    if (currentVertexIndex != SHADOW_VERTEX_COUNT) {
+        ALOGE("number of vertex generated for ambient shadow is wrong! "
+              "current: %d , expected: %d", currentVertexIndex, SHADOW_VERTEX_COUNT);
     }
+    for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) {
+        ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
+                shadowVertices[i].y, shadowVertices[i].alpha);
+    }
+#endif
 }
 
 /**
@@ -238,7 +168,7 @@
  * @param outRayDist Return the ray distance from centroid to the intersection.
  */
 void AmbientShadow::calculateIntersection(const Vector3* vertices, int vertexCount,
-        const Vector2& start, const Vector2& dir, int& outEdgeIndex,
+        const Vector3& start, const Vector2& dir, int& outEdgeIndex,
         float& outEdgeFraction, float& outRayDist) {
     float startX = start.x;
     float startY = start.y;
diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h
index 079bdb7..20d1384 100644
--- a/libs/hwui/AmbientShadow.h
+++ b/libs/hwui/AmbientShadow.h
@@ -34,17 +34,15 @@
  */
 class AmbientShadow {
 public:
-    static void createAmbientShadow(const Vector3* poly, int polyLength, int rays,
-            int layers, float strength, float heightFactor, float geomFactor,
+    static void createAmbientShadow(const Vector3* poly, int polyLength,
+            const Vector3& centroid3d, float heightFactor, float geomFactor,
             VertexBuffer& shadowVertexBuffer);
 
 private:
-    static void calculatePolygonCentroid(const Vector3* poly, int len, Vector2& centroid);
-
     static void calculateRayDirections(int rays, Vector2* dir);
 
     static void calculateIntersection(const Vector3* poly, int nbVertices,
-            const Vector2& start, const Vector2& dir, int& outEdgeIndex,
+            const Vector3& start, const Vector2& dir, int& outEdgeIndex,
             float& outEdgeFraction, float& outRayDist);
 
     static void calculateNormal(int rays, int currentRayIndex, const Vector2* dir,
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 495ad19..2cc7a84 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -61,12 +61,7 @@
 	LOCAL_C_INCLUDES += \
 		$(JNI_H_INCLUDE) \
 		$(LOCAL_PATH)/../../include/utils \
-		external/skia/include/core \
-		external/skia/include/effects \
-		external/skia/include/images \
-		external/skia/src/core \
-		external/skia/src/ports \
-		external/skia/include/utils
+		external/skia/src/core
 
 	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
 	LOCAL_CFLAGS += -Wno-unused-parameter
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 21cf658..1d58d96 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -23,6 +23,7 @@
 #include "DisplayListRenderer.h"
 #include "Properties.h"
 #include "LayerRenderer.h"
+#include "ShadowTessellator.h"
 
 namespace android {
 
@@ -86,7 +87,7 @@
 
     mRegionMesh = NULL;
     mMeshIndices = 0;
-
+    mShadowStripsIndices = 0;
     blend = false;
     lastSrcMode = GL_ZERO;
     lastDstMode = GL_ZERO;
@@ -223,6 +224,9 @@
     mMeshIndices = 0;
     mRegionMesh = NULL;
 
+    glDeleteBuffers(1, &mShadowStripsIndices);
+    mShadowStripsIndices = 0;
+
     fboCache.clear();
 
     programCache.clear();
@@ -404,7 +408,7 @@
     return false;
 }
 
-bool Caches::bindIndicesBuffer(const GLuint buffer) {
+bool Caches::bindIndicesBufferInternal(const GLuint buffer) {
     if (mCurrentIndicesBuffer != buffer) {
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
         mCurrentIndicesBuffer = buffer;
@@ -413,7 +417,7 @@
     return false;
 }
 
-bool Caches::bindIndicesBuffer() {
+bool Caches::bindQuadIndicesBuffer() {
     if (!mMeshIndices) {
         uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6];
         for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) {
@@ -428,7 +432,7 @@
         }
 
         glGenBuffers(1, &mMeshIndices);
-        bool force = bindIndicesBuffer(mMeshIndices);
+        bool force = bindIndicesBufferInternal(mMeshIndices);
         glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t),
                 regionIndices, GL_STATIC_DRAW);
 
@@ -436,7 +440,23 @@
         return force;
     }
 
-    return bindIndicesBuffer(mMeshIndices);
+    return bindIndicesBufferInternal(mMeshIndices);
+}
+
+bool Caches::bindShadowIndicesBuffer() {
+    if (!mShadowStripsIndices) {
+        uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT];
+        ShadowTessellator::generateShadowIndices(shadowIndices);
+        glGenBuffers(1, &mShadowStripsIndices);
+        bool force = bindIndicesBufferInternal(mShadowStripsIndices);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t),
+            shadowIndices, GL_STATIC_DRAW);
+
+        delete[] shadowIndices;
+        return force;
+    }
+
+    return bindIndicesBufferInternal(mShadowStripsIndices);
 }
 
 bool Caches::unbindIndicesBuffer() {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 2cc15cc..8c0c508 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -190,8 +190,8 @@
      * Binds a global indices buffer that can draw up to
      * gMaxNumberOfQuads quads.
      */
-    bool bindIndicesBuffer();
-    bool bindIndicesBuffer(const GLuint buffer);
+    bool bindQuadIndicesBuffer();
+    bool bindShadowIndicesBuffer();
     bool unbindIndicesBuffer();
 
     /**
@@ -381,6 +381,8 @@
     void initConstraints();
     void initStaticProperties();
 
+    bool bindIndicesBufferInternal(const GLuint buffer);
+
     static void eventMarkNull(GLsizei length, const GLchar* marker) { }
     static void startMarkNull(GLsizei length, const GLchar* marker) { }
     static void endMarkNull() { }
@@ -417,6 +419,7 @@
 
     // Global index buffer
     GLuint mMeshIndices;
+    GLuint mShadowStripsIndices;
 
     mutable Mutex mGarbageLock;
     Vector<Layer*> mLayerGarbage;
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 62f6c76..7a2e288 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -112,6 +112,15 @@
             frameNumber = newFrameNumber;
             dropCounter++;
         }
+
+        bool forceFilter = false;
+        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
+        if (buffer != NULL) {
+            // force filtration if buffer size != layer size
+            forceFilter = mWidth != buffer->getWidth()
+                    || mHeight != buffer->getHeight();
+        }
+
         #if DEBUG_RENDERER
         if (dropCounter > 0) {
             RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
@@ -120,8 +129,8 @@
         mSurfaceTexture->getTransformMatrix(transform);
         GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
 
-        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight, !mBlend,
-                renderTarget, transform);
+        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight,
+                !mBlend, forceFilter, renderTarget, transform);
     }
 }
 
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index b5a66f6..65eda29 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -788,7 +788,7 @@
         deferInfo.mergeable = state.mMatrix.isSimple() && state.mMatrix.positiveScale() &&
                 !state.mClipSideFlags &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode &&
-                (mBitmap->getConfig() != SkBitmap::kA8_Config);
+                (mBitmap->config() != SkBitmap::kA8_Config);
     }
 
     const SkBitmap* bitmap() { return mBitmap; }
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index b79a3b0..b52003c 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -498,7 +498,7 @@
                 }
 
                 checkTextureUpdate();
-                caches.bindIndicesBuffer();
+                caches.bindQuadIndicesBuffer();
 
                 if (!mDrawn) {
                     // If returns true, a VBO was bound and we must
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 54ce64f..8992a13 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -46,6 +46,7 @@
     stencil = NULL;
     debugDrawUpdate = false;
     hasDrawnSinceUpdate = false;
+    forceFilter = false;
     deferredList = NULL;
     caches.resourceCache.incrementRefcount(this);
 }
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 8cc027a..f6538f2 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -127,6 +127,14 @@
         return texture.blend;
     }
 
+    inline void setForceFilter(bool forceFilter) {
+        this->forceFilter = forceFilter;
+    }
+
+    inline bool getForceFilter() const {
+        return forceFilter;
+    }
+
     inline void setAlpha(int alpha) {
         this->alpha = alpha;
     }
@@ -343,9 +351,15 @@
     SkColorFilter* colorFilter;
 
     /**
+     * Indicates raster data backing the layer is scaled, requiring filtration.
+     */
+    bool forceFilter;
+
+    /**
      * Opacity of the layer.
      */
     int alpha;
+
     /**
      * Blending mode of the layer.
      */
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index ea8eb31..e0ac2ba 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -290,14 +290,15 @@
 }
 
 void LayerRenderer::updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
-        bool isOpaque, GLenum renderTarget, float* transform) {
+        bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform) {
     if (layer) {
         layer->setBlend(!isOpaque);
+        layer->setForceFilter(forceFilter);
         layer->setSize(width, height);
         layer->layer.set(0.0f, 0.0f, width, height);
         layer->region.set(width, height);
         layer->regionRect.set(0.0f, 0.0f, width, height);
-        layer->getTexTransform().load(transform);
+        layer->getTexTransform().load(textureTransform);
 
         if (renderTarget != layer->getRenderTarget()) {
             layer->setRenderTarget(renderTarget);
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 84acd44..40e461a 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -56,7 +56,7 @@
     ANDROID_API static Layer* createRenderLayer(uint32_t width, uint32_t height);
     ANDROID_API static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
     ANDROID_API static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
-            bool isOpaque, GLenum renderTarget, float* transform);
+            bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform);
     ANDROID_API static void destroyLayer(Layer* layer);
     ANDROID_API static void destroyLayerDeferred(Layer* layer);
     ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 75bf716..b620b80 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -52,7 +52,12 @@
 
 #define ALPHA_THRESHOLD 0
 
-#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
+static GLenum getFilter(const SkPaint* paint) {
+    if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) {
+        return GL_LINEAR;
+    }
+    return GL_NEAREST;
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 // Globals
@@ -1068,6 +1073,7 @@
         setupDrawExternalTexture(layer->getTexture());
     }
     if (currentTransform()->isPureTranslate() &&
+            !layer->getForceFilter() &&
             layer->getWidth() == (uint32_t) rect.getWidth() &&
             layer->getHeight() == (uint32_t) rect.getHeight()) {
         const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
@@ -1902,7 +1908,7 @@
     } else {
         force = mCaches.unbindMeshBuffer();
     }
-    mCaches.bindIndicesBuffer();
+    mCaches.bindQuadIndicesBuffer();
 
     mCaches.bindPositionVertexPointer(force, vertices);
     if (mCaches.currentProgram->texCoords >= 0) {
@@ -1912,7 +1918,7 @@
 
 void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
     bool force = mCaches.unbindMeshBuffer();
-    mCaches.bindIndicesBuffer();
+    mCaches.bindQuadIndicesBuffer();
     mCaches.bindPositionVertexPointer(force, vertices, gVertexStride);
 }
 
@@ -1972,7 +1978,7 @@
 
         texture->setFilter(GL_NEAREST, true);
     } else {
-        texture->setFilter(FILTER(paint), true);
+        texture->setFilter(getFilter(paint), true);
     }
 
     // No need to check for a UV mapper on the texture object, only ARGB_8888
@@ -1997,7 +2003,7 @@
     const AutoTexture autoCleanup(texture);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(pureTranslate ? GL_NEAREST : FILTER(paint), true);
+    texture->setFilter(pureTranslate ? GL_NEAREST : getFilter(paint), true);
 
     const float x = (int) floorf(bounds.left + 0.5f);
     const float y = (int) floorf(bounds.top + 0.5f);
@@ -2173,7 +2179,7 @@
     const AutoTexture autoCleanup(texture);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(FILTER(paint), true);
+    texture->setFilter(getFilter(paint), true);
 
     int alpha;
     SkXfermode::Mode mode;
@@ -2258,10 +2264,10 @@
         dstLeft = x;
         dstTop = y;
 
-        texture->setFilter(scaled ? FILTER(paint) : GL_NEAREST, true);
+        texture->setFilter(scaled ? getFilter(paint) : GL_NEAREST, true);
         ignoreTransform = true;
     } else {
-        texture->setFilter(FILTER(paint), true);
+        texture->setFilter(getFilter(paint), true);
     }
 
     if (CC_UNLIKELY(useScaleTransform)) {
@@ -2387,10 +2393,9 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint,
-        bool useOffset) {
+status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode,
+        const VertexBuffer& vertexBuffer, const SkPaint* paint, bool useOffset) {
     // not missing call to quickReject/dirtyLayer, always done at a higher level
-
     if (!vertexBuffer.getVertexCount()) {
         // no vertices to draw
         return DrawGlInfo::kStatusDone;
@@ -2416,19 +2421,24 @@
     bool force = mCaches.unbindMeshBuffer();
     mCaches.bindPositionVertexPointer(true, vertices, isAA ? gAlphaVertexStride : gVertexStride);
     mCaches.resetTexCoordsVertexPointer();
-    mCaches.unbindIndicesBuffer();
+
 
     int alphaSlot = -1;
     if (isAA) {
         void* alphaCoords = ((GLbyte*) vertices) + gVertexAlphaOffset;
         alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha");
-
         // TODO: avoid enable/disable in back to back uses of the alpha attribute
         glEnableVertexAttribArray(alphaSlot);
         glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
     }
 
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
+    if (mode == kVertexBufferMode_Standard) {
+        mCaches.unbindIndicesBuffer();
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
+    } else {
+        mCaches.bindShadowIndicesBuffer();
+        glDrawElements(GL_TRIANGLE_STRIP, SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
+    }
 
     if (isAA) {
         glDisableVertexAttribArray(alphaSlot);
@@ -2457,7 +2467,7 @@
         dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
     }
 
-    return drawVertexBuffer(vertexBuffer, paint);
+    return drawVertexBuffer(kVertexBufferMode_Standard, vertexBuffer, paint);
 }
 
 /**
@@ -2488,7 +2498,7 @@
     dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    return drawVertexBuffer(kVertexBufferMode_Standard, buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
@@ -2508,7 +2518,7 @@
     dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    return drawVertexBuffer(kVertexBufferMode_Standard, buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -3231,13 +3241,20 @@
         casterTransform.mapPoint3d(casterPolygon[i]);
     }
 
+    // map the centroid of the caster into 3d
+    Vector2 centroid =  ShadowTessellator::centroid2d(
+            reinterpret_cast<const Vector2*>(casterVertices2d.array()),
+            casterVertexCount);
+    Vector3 centroid3d(centroid.x, centroid.y, 0);
+    casterTransform.mapPoint3d(centroid3d);
+
     // draw caster's shadows
     if (mCaches.propertyAmbientShadowStrength > 0) {
         paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0);
         VertexBuffer ambientShadowVertexBuffer;
         ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
-                ambientShadowVertexBuffer);
-        drawVertexBuffer(ambientShadowVertexBuffer, &paint);
+                centroid3d, ambientShadowVertexBuffer);
+        drawVertexBuffer(kVertexBufferMode_Shadow, ambientShadowVertexBuffer, &paint);
     }
 
     if (mCaches.propertySpotShadowStrength > 0) {
@@ -3249,7 +3266,7 @@
                 lightPosScale, *currentTransform(), getWidth(), getHeight(),
                 spotShadowVertexBuffer);
 
-        drawVertexBuffer(spotShadowVertexBuffer, &paint);
+        drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint);
     }
 
     return DrawGlInfo::kStatusDrew;
@@ -3370,7 +3387,7 @@
                 paint, texture->blend, vertices, texCoords,
                 GL_TRIANGLE_STRIP, gMeshCount, false, true);
     } else {
-        texture->setFilter(FILTER(paint), true);
+        texture->setFilter(getFilter(paint), true);
         drawTextureMesh(left, top, right, bottom, texture->id, paint,
                 texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, gMeshCount);
     }
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e4d133d..03beae3 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -117,6 +117,11 @@
     kModelViewMode_TranslateAndScale = 1,
 };
 
+enum VertexBufferMode {
+    kVertexBufferMode_Standard = 0,
+    kVertexBufferMode_Shadow = 1
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
@@ -629,8 +634,8 @@
      * @param paint The paint to render with
      * @param useOffset Offset the vertexBuffer (used in drawing non-AA lines)
      */
-    status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, const SkPaint* paint,
-            bool useOffset = false);
+    status_t drawVertexBuffer(VertexBufferMode mode, const VertexBuffer& vertexBuffer,
+            const SkPaint* paint, bool useOffset = false);
 
     /**
      * Renders the convex hull defined by the specified path as a strip of polygons.
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
index dc0d98c..8a44604 100644
--- a/libs/hwui/PatchCache.cpp
+++ b/libs/hwui/PatchCache.cpp
@@ -129,7 +129,11 @@
         Mutex::Autolock _l(mLock);
         size_t count = mGarbage.size();
         for (size_t i = 0; i < count; i++) {
-            remove(patchesToRemove, mGarbage[i]);
+            Res_png_9patch* patch = mGarbage[i];
+            remove(patchesToRemove, patch);
+            // A Res_png_9patch is actually an array of byte that's larger
+            // than sizeof(Res_png_9patch). It must be freed as an array.
+            delete[] (int8_t*) patch;
         }
         mGarbage.clear();
     }
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 9459885..5a49f38 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -395,7 +395,9 @@
         Mutex::Autolock l(mLock);
         size_t count = mGarbage.size();
         for (size_t i = 0; i < count; i++) {
-            remove(pathsToRemove, mGarbage.itemAt(i));
+            const path_pair_t& pair = mGarbage.itemAt(i);
+            remove(pathsToRemove, pair);
+            delete pair.getFirst();
         }
         mGarbage.clear();
     }
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 457cfa9..5562f34 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -193,8 +193,9 @@
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
             Caches::getInstance().pathCache.removeDeferred(resource);
+        } else {
+            delete resource;
         }
-        delete resource;
         return;
     }
     ref->destroyed = true;
@@ -215,8 +216,9 @@
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
             Caches::getInstance().textureCache.removeDeferred(resource);
+        } else {
+            delete resource;
         }
-        delete resource;
         return;
     }
     ref->destroyed = true;
@@ -253,13 +255,14 @@
     ssize_t index = mCache->indexOfKey(resource);
     ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
+        // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
             Caches::getInstance().patchCache.removeDeferred(resource);
+        } else {
+            // A Res_png_9patch is actually an array of byte that's larger
+            // than sizeof(Res_png_9patch). It must be freed as an array.
+            delete[] (int8_t*) resource;
         }
-        // If we're not tracking this resource, just delete it
-        // A Res_png_9patch is actually an array of byte that's larger
-        // than sizeof(Res_png_9patch). It must be freed as an array.
-        delete[] (int8_t*) resource;
         return;
     }
     ref->destroyed = true;
@@ -316,16 +319,18 @@
                 SkBitmap* bitmap = (SkBitmap*) resource;
                 if (Caches::hasInstance()) {
                     Caches::getInstance().textureCache.removeDeferred(bitmap);
+                } else {
+                    delete bitmap;
                 }
-                delete bitmap;
             }
             break;
             case kPath: {
                 SkPath* path = (SkPath*) resource;
                 if (Caches::hasInstance()) {
                     Caches::getInstance().pathCache.removeDeferred(path);
+                } else {
+                    delete path;
                 }
-                delete path;
             }
             break;
             case kShader: {
@@ -336,11 +341,12 @@
             case kNinePatch: {
                 if (Caches::hasInstance()) {
                     Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);
+                } else {
+                    // A Res_png_9patch is actually an array of byte that's larger
+                    // than sizeof(Res_png_9patch). It must be freed as an array.
+                    int8_t* patch = (int8_t*) resource;
+                    delete[] patch;
                 }
-                // A Res_png_9patch is actually an array of byte that's larger
-                // than sizeof(Res_png_9patch). It must be freed as an array.
-                int8_t* patch = (int8_t*) resource;
-                delete[] patch;
             }
             break;
             case kLayer: {
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 7700ea0..526772b 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -31,18 +31,16 @@
     return a > b ? a : b;
 }
 
-void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon, int casterVertexCount,
+void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon,
+        int casterVertexCount, const Vector3& centroid3d,
         VertexBuffer& shadowVertexBuffer) {
     // A bunch of parameters to tweak the shadow.
     // TODO: Allow some of these changable by debug settings or APIs.
-    const int rays = 128;
-    const int layers = 2;
-    const float strength = 0.5;
     const float heightFactor = 128;
     const float geomFactor = 64;
 
-    AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount, rays, layers, strength,
-            heightFactor, geomFactor, shadowVertexBuffer);
+    AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount,
+            centroid3d, heightFactor, geomFactor, shadowVertexBuffer);
 
 }
 
@@ -51,9 +49,6 @@
         int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) {
     // A bunch of parameters to tweak the shadow.
     // TODO: Allow some of these changable by debug settings or APIs.
-    const int rays = 256;
-    const int layers = 2;
-    const float strength = 0.5;
     int maximal = max(screenWidth, screenHeight);
     Vector3 lightCenter(screenWidth * lightPosScale.x, screenHeight * lightPosScale.y,
             maximal * lightPosScale.z);
@@ -70,9 +65,77 @@
     const float lightSize = maximal / 4;
     const int lightVertexCount = 16;
 
-    SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter, lightSize,
-            lightVertexCount, rays, layers, strength, shadowVertexBuffer);
+    SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter,
+            lightSize, lightVertexCount, shadowVertexBuffer);
 
 }
+
+void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) {
+    int currentIndex = 0;
+    const int layers = SHADOW_LAYER_COUNT;
+    const int rays = SHADOW_RAY_COUNT;
+    // For the penumbra area.
+    for (int i = 0; i < layers; i++) {
+        for (int j = 0; j < rays; j++) {
+            shadowIndices[currentIndex++] = i * rays + j;
+            shadowIndices[currentIndex++] = (i + 1) * rays + j;
+        }
+        // To close the loop, back to the ray 0.
+        shadowIndices[currentIndex++] = i * rays;
+        shadowIndices[currentIndex++] = (i + 1) * rays;
+    }
+    uint16_t base = layers * rays;
+    uint16_t centroidIndex = (layers + 1) * rays;
+    // For the umbra area, using strips to simulate the fans.
+    for (int k = 0; k < rays; k++) {
+        shadowIndices[currentIndex++] = base + k;
+        shadowIndices[currentIndex++] = centroidIndex;
+    }
+    shadowIndices[currentIndex++] = base;
+
+#if DEBUG_SHADOW
+    if (currentIndex != SHADOW_INDEX_COUNT) {
+        ALOGE("vertex index count is wrong. current %d, expected %d",
+                currentIndex, SHADOW_INDEX_COUNT);
+    }
+    for (int i = 0; i < SHADOW_INDEX_COUNT; i++) {
+        ALOGD("vertex index is (%d, %d)", i, shadowIndices[i]);
+    }
+#endif
+}
+
+/**
+ * Calculate the centroid of a 2d polygon.
+ *
+ * @param poly The polygon, which is represented in a Vector2 array.
+ * @param polyLength The length of the polygon in terms of number of vertices.
+ * @return the centroid of the polygon.
+ */
+Vector2 ShadowTessellator::centroid2d(const Vector2* poly, int polyLength) {
+    double sumx = 0;
+    double sumy = 0;
+    int p1 = polyLength - 1;
+    double area = 0;
+    for (int p2 = 0; p2 < polyLength; p2++) {
+        double x1 = poly[p1].x;
+        double y1 = poly[p1].y;
+        double x2 = poly[p2].x;
+        double y2 = poly[p2].y;
+        double a = (x1 * y2 - x2 * y1);
+        sumx += (x1 + x2) * a;
+        sumy += (y1 + y2) * a;
+        area += a;
+        p1 = p2;
+    }
+
+    Vector2 centroid = poly[0];
+    if (area != 0) {
+        centroid = Vector2(sumx / (3 * area), sumy / (3 * area));
+    } else {
+        ALOGE("Area is 0 while computing centroid!");
+    }
+    return centroid;
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index ef95609..c49fdcb1 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -20,18 +20,57 @@
 
 #include "Debug.h"
 #include "Matrix.h"
+#include "VertexBuffer.h"
 
 namespace android {
 namespace uirenderer {
 
+// All SHADOW_* are used to define all the geometry property of shadows.
+// Use a simplified example to illustrate the geometry setup here.
+// Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which
+// are 0 to 5 and 6 to 11. The area between them will be the penumbra area, and
+// the area inside the 2nd hexagon is the umbra.
+// Also, we need to add the centroid "12" to draw the umbra area as triangle fans.
+//
+// Triange strip indices for penumbra area: (0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 0, 6)
+// Triange strip indices for numbra area: (6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 6)
+//                 0
+//
+//      5          6         1
+//           11         7
+//                12
+//           10         8
+//      4          9         2
+//
+//                 3
+
+// The total number of rays starting from the centroid of shadow area, in order
+// to generate the shadow geometry.
+#define SHADOW_RAY_COUNT 256
+
+// The total number of layers in the outer shadow area, 1 being the minimum.
+#define SHADOW_LAYER_COUNT 2
+
+// The total number of all the vertices representing the shadow.
+#define SHADOW_VERTEX_COUNT ((SHADOW_LAYER_COUNT + 1) * SHADOW_RAY_COUNT + 1)
+
+// The total number of indices used for drawing the shadow geometry as triangle strips.
+#define SHADOW_INDEX_COUNT (2 * SHADOW_RAY_COUNT + 1 + 2 * (SHADOW_RAY_COUNT + 1) * \
+        SHADOW_LAYER_COUNT)
+
 class ShadowTessellator {
 public:
-    static void tessellateAmbientShadow(const Vector3* casterPolygon, int casterVertexCount,
+    static void tessellateAmbientShadow(const Vector3* casterPolygon,
+            int casterVertexCount, const Vector3& centroid3d,
             VertexBuffer& shadowVertexBuffer);
 
     static void tessellateSpotShadow(const Vector3* casterPolygon, int casterVertexCount,
             const Vector3& lightPosScale, const mat4& receiverTransform,
             int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer);
+
+    static void generateShadowIndices(uint16_t*  shadowIndices);
+
+    static Vector2 centroid2d(const Vector2* poly, int polyLength);
 }; // ShadowTessellator
 
 }; // namespace uirenderer
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index 4c2299e..22d735b 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <utils/Log.h>
 
+#include "ShadowTessellator.h"
 #include "SpotShadow.h"
 #include "Vertex.h"
 
@@ -70,35 +71,6 @@
 }
 
 /**
- * Calculate the centroid of a 2d polygon.
- *
- * @param poly The polygon, which is represented in a Vector2 array.
- * @param polyLength The length of the polygon in terms of number of vertices.
- * @return the centroid of the polygon.
- */
-Vector2 SpotShadow::centroid2d(const Vector2* poly, int polyLength) {
-    double sumx = 0;
-    double sumy = 0;
-    int p1 = polyLength - 1;
-    double area = 0;
-    for (int p2 = 0; p2 < polyLength; p2++) {
-        double x1 = poly[p1].x;
-        double y1 = poly[p1].y;
-        double x2 = poly[p2].x;
-        double y2 = poly[p2].y;
-        double a = (x1 * y2 - x2 * y1);
-        sumx += (x1 + x2) * a;
-        sumy += (y1 + y2) * a;
-        area += a;
-        p1 = p2;
-    }
-
-    double centroidx = sumx / (3 * area);
-    double centroidy = sumy / (3 * area);
-    return Vector2((float)centroidx, (float)centroidy);
-}
-
-/**
  * Sort points by their X coordinates
  *
  * @param points the points as a Vector2 array.
@@ -550,20 +522,17 @@
 * @param lightCenter the center of the light
 * @param lightSize the radius of the light source
 * @param lightVertexCount the vertex counter for the light polygon
-* @param rays the number of vertexes to create along the edges of the shadow
-* @param layers the number of layers of triangles strips to create
-* @param strength the "darkness" of the shadow
 * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
 *                            empty strip if error.
 *
 */
 void SpotShadow::createSpotShadow(const Vector3* poly, int polyLength,
         const Vector3& lightCenter, float lightSize, int lightVertexCount,
-        int rays, int layers, float strength, VertexBuffer& retStrips) {
+        VertexBuffer& retStrips) {
     Vector3 light[lightVertexCount * 3];
     computeLightPolygon(lightVertexCount, lightCenter, lightSize, light);
-    computeSpotShadow(light, lightVertexCount, lightCenter,
-            poly, polyLength, rays, layers, strength, retStrips);
+    computeSpotShadow(light, lightVertexCount, lightCenter, poly, polyLength,
+            retStrips);
 }
 
 /**
@@ -573,15 +542,12 @@
  * @param lightPolyLength number of vertexes of the light source polygon
  * @param poly x,y,z vertexes of a convex polygon that occludes the light source
  * @param polyLength number of vertexes of the occluding polygon
- * @param rays the number of vertexes to create along the edges of the shadow
- * @param layers the number of layers of triangles strips to create
- * @param strength the "darkness" of the shadow
  * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
  *                            empty strip if error.
  */
 void SpotShadow::computeSpotShadow(const Vector3* lightPoly, int lightPolyLength,
         const Vector3& lightCenter, const Vector3* poly, int polyLength,
-        int rays, int layers, float strength, VertexBuffer& shadowTriangleStrip) {
+        VertexBuffer& shadowTriangleStrip) {
     // Point clouds for all the shadowed vertices
     Vector2 shadowRegion[lightPolyLength * polyLength];
     // Shadow polygon from one point light.
@@ -671,7 +637,8 @@
 
         // Shrink the centroid's shadow by 10%.
         // TODO: Study the magic number of 10%.
-        Vector2 shadowCentroid = centroid2d(fakeUmbra, polyLength);
+        Vector2 shadowCentroid =
+                ShadowTessellator::centroid2d(fakeUmbra, polyLength);
         for (int i = 0; i < polyLength; i++) {
             fakeUmbra[i] = shadowCentroid * (1.0f - SHADOW_SHRINK_SCALE) +
                     fakeUmbra[i] * SHADOW_SHRINK_SCALE;
@@ -686,7 +653,7 @@
     }
 
     generateTriangleStrip(penumbra, penumbraLength, umbra, umbraLength,
-            rays, layers, strength, shadowTriangleStrip);
+            shadowTriangleStrip);
 }
 
 /**
@@ -696,22 +663,18 @@
  * @param penumbraLength The number of vertexes in the outer polygon
  * @param umbra The inner outer polygon x,y vertexes
  * @param umbraLength The number of vertexes in the inner polygon
- * @param rays The number of points along the polygons to create
- * @param layers The number of layers of triangle strips between the umbra and penumbra
- * @param strength The max alpha of the umbra
  * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
  *                            empty strip if error.
 **/
 void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
-        const Vector2* umbra, int umbraLength, int rays, int layers,
-        float strength, VertexBuffer& shadowTriangleStrip) {
+        const Vector2* umbra, int umbraLength, VertexBuffer& shadowTriangleStrip) {
+    const int rays = SHADOW_RAY_COUNT;
+    const int layers = SHADOW_LAYER_COUNT;
 
-    int rings = layers + 1;
-    int size = rays * rings;
-
+    int size = rays * (layers + 1);
     float step = M_PI * 2 / rays;
     // Centroid of the umbra.
-    Vector2 centroid = centroid2d(umbra, umbraLength);
+    Vector2 centroid = ShadowTessellator::centroid2d(umbra, umbraLength);
 #if DEBUG_SHADOW
     ALOGD("centroid2d =  %f , %f", centroid.x, centroid.y);
 #endif
@@ -741,57 +704,29 @@
     int stripSize = getStripSize(rays, layers);
     AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(stripSize);
     int currentIndex = 0;
-    int firstInLayer = 0;
-    // Calculate the vertex values in the penumbra area.
-    for (int r = 0; r < layers; r++) {
-        firstInLayer = currentIndex;
-        for (int i = 0; i < rays; i++) {
-            float dx = sinf(step * i);
-            float dy = cosf(step * i);
 
-            for (int j = r; j < (r + 2); j++) {
-                float layerRatio = j / (float)(rings - 1);
-                float deltaDist = layerRatio * (umbraDistPerRay[i] - penumbraDistPerRay[i]);
-                float currentDist = penumbraDistPerRay[i] + deltaDist;
-                float op = calculateOpacity(layerRatio, deltaDist);
+    // Calculate the vertices (x, y, alpha) in the shadow area.
+    for (int layerIndex = 0; layerIndex <= layers; layerIndex++) {
+        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+            float dx = sinf(step * rayIndex);
+            float dy = cosf(step * rayIndex);
+                float layerRatio = layerIndex / (float) layers;
+                float deltaDist = layerRatio *
+                        (umbraDistPerRay[rayIndex] - penumbraDistPerRay[rayIndex]);
+                float currentDist = penumbraDistPerRay[rayIndex] + deltaDist;
+                float op = calculateOpacity(layerRatio);
                 AlphaVertex::set(&shadowVertices[currentIndex++],
-                        dx * currentDist + centroid.x,
-                        dy * currentDist + centroid.y,
-                        layerRatio * op * strength);
-            }
+                        dx * currentDist + centroid.x, dy * currentDist + centroid.y, op);
         }
-
-        // Duplicate the vertices from one layer to another one to make triangle
-        // strip.
-        shadowVertices[currentIndex++] = shadowVertices[firstInLayer + 0];
-        shadowVertices[currentIndex++] = shadowVertices[firstInLayer + 1];
     }
-
-    int lastInPenumbra = currentIndex - 1;
-    shadowVertices[currentIndex++] = shadowVertices[lastInPenumbra];
-
-    // Preallocate the vertices (index as [firstInUmbra - 1]) for jumping from
-    // the penumbra to umbra.
-    currentIndex++;
-    int firstInUmbra = currentIndex;
-
-    // traverse the umbra area in a zig zag pattern for strips.
-    const int innerRingStartIndex = firstInLayer + 1;
-    for (int k = 0; k < rays; k++) {
-        int i = k / 2;
-        if ((k & 1) == 1) {
-            i = rays - i - 1;
-        }
-        // copy already computed values for umbra vertices
-        shadowVertices[currentIndex++] = shadowVertices[innerRingStartIndex + i * 2];
-    }
-
-    // Back fill the one vertex for jumping from penumbra to umbra.
-    shadowVertices[firstInUmbra - 1] = shadowVertices[firstInUmbra];
-
+    // The centroid is in the umbra area, so the opacity is considered as 1.0.
+    AlphaVertex::set(&shadowVertices[currentIndex++], centroid.x, centroid.y, 1.0);
 #if DEBUG_SHADOW
+    if (currentIndex != SHADOW_VERTEX_COUNT) {
+        ALOGE("number of vertex generated for spot shadow is wrong!");
+    }
     for (int i = 0; i < currentIndex; i++) {
-        ALOGD("shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
+        ALOGD("spot shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
                 shadowVertices[i].y, shadowVertices[i].alpha);
     }
 #endif
@@ -819,17 +754,15 @@
 }
 
 /**
- * Calculate the opacity according to the distance and falloff ratio.
+ * Calculate the opacity according to the distance. Ideally, the opacity is 1.0
+ * in the umbra area, and fall off to 0.0 till the edge of penumbra area.
  *
- * @param distRatio The distance ratio of current sample between umbra and
- *                  penumbra area.
- * @param deltaDist The distance between current sample to the penumbra area.
+ * @param layerRatio The distance ratio of current sample between umbra and penumbra area.
+ *                   Penumbra edge is 0 and umbra edge is 1.
  * @return The opacity according to the distance between umbra and penumbra.
  */
-float SpotShadow::calculateOpacity(float distRatio, float deltaDist) {
-    // TODO: Experiment on the opacity calculation.
-    float falloffRatio = 1 + deltaDist * deltaDist;
-    return (distRatio + 1 - 1 / falloffRatio) / 2;
+float SpotShadow::calculateOpacity(float layerRatio) {
+    return (layerRatio * layerRatio + layerRatio) / 2.0;
 }
 
 /**
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index a50d110..6727eac 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -28,24 +28,22 @@
 public:
     static void createSpotShadow(const Vector3* poly, int polyLength,
             const Vector3& lightCenter, float lightSize, int lightVertexCount,
-            int rays, int layers, float strength, VertexBuffer& retStrips);
+            VertexBuffer& retStrips);
 
 private:
     static void computeSpotShadow(const Vector3* lightPoly, int lightPolyLength,
             const Vector3& lightCenter, const Vector3* poly, int polyLength,
-            int rays, int layers, float strength, VertexBuffer& retstrips);
+            VertexBuffer& retstrips);
 
     static void computeLightPolygon(int points, const Vector3& lightCenter,
             float size, Vector3* ret);
 
     static int  getStripSize(int rays, int layers);
     static void smoothPolygon(int level, int rays, float* rayDist);
-    static float calculateOpacity(float jf, float deltaDist);
+    static float calculateOpacity(float jf);
     static float rayIntersectPoly(const Vector2* poly, int polyLength,
             const Vector2& point, float dx, float dy);
 
-    static Vector2 centroid2d(const Vector2* poly, int polyLength);
-
     static void xsort(Vector2* points, int pointsLength);
     static int hull(Vector2* points, int pointsLength, Vector2* retPoly);
     static bool ccw(double ax, double ay, double bx, double by, double cx, double cy);
@@ -65,8 +63,7 @@
             double x3, double y3, double x4, double y4, Vector2& ret);
 
     static void generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
-            const Vector2* umbra, int umbraLength, int rays, int layers,
-            float strength, VertexBuffer& retstrips);
+            const Vector2* umbra, int umbraLength, VertexBuffer& retstrips);
 
     static const double EPSILON = 1e-7;
 
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 467f6ca..01d72d1 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -184,7 +184,9 @@
     Mutex::Autolock _l(mLock);
     size_t count = mGarbage.size();
     for (size_t i = 0; i < count; i++) {
-        mCache.remove(mGarbage.itemAt(i));
+        const SkBitmap* bitmap = mGarbage.itemAt(i);
+        mCache.remove(bitmap);
+        delete bitmap;
     }
     mGarbage.clear();
 }
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index 6011ff0..a7fb0e2 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -31,7 +31,6 @@
 	libinputflinger
 
 LOCAL_C_INCLUDES := \
-    external/skia/include/core \
     frameworks/native/services
 
 
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
index 300224a..3e07155 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
@@ -11,7 +11,6 @@
 
 LOCAL_MODULE := accessorychat
 
-LOCAL_C_INCLUDES += bionic/libc/kernel/common
 LOCAL_STATIC_LIBRARIES := libusbhost libcutils
 LOCAL_LDLIBS += -lpthread
 LOCAL_CFLAGS := -g -O0
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h b/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h
new file mode 100644
index 0000000..75e017c
--- /dev/null
+++ b/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H
+#define _UAPI_LINUX_USB_F_ACCESSORY_H
+#define USB_ACCESSORY_VENDOR_ID 0x18D1
+#define USB_ACCESSORY_PRODUCT_ID 0x2D00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
+#define ACCESSORY_STRING_MANUFACTURER 0
+#define ACCESSORY_STRING_MODEL 1
+#define ACCESSORY_STRING_DESCRIPTION 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_STRING_VERSION 3
+#define ACCESSORY_STRING_URI 4
+#define ACCESSORY_STRING_SERIAL 5
+#define ACCESSORY_GET_PROTOCOL 51
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SEND_STRING 52
+#define ACCESSORY_START 53
+#define ACCESSORY_REGISTER_HID 54
+#define ACCESSORY_UNREGISTER_HID 55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SET_HID_REPORT_DESC 56
+#define ACCESSORY_SEND_HID_EVENT 57
+#define ACCESSORY_SET_AUDIO_MODE 58
+#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256])
+#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256])
+#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256])
+#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256])
+#define ACCESSORY_IS_START_REQUESTED _IO('M', 7)
+#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index ccb4304..36778aa 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 
+import java.lang.SecurityException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -1104,13 +1105,18 @@
      * unless they depend on provider-specific APIs such as
      * {@link #requestLocationUpdates(String, long, float, LocationListener)}.
      *
+     * <p>
+     * Before API version 20, this method would throw {@link SecurityException}
+     * if the location permissions were not sufficient to use the specified
+     * provider.
+     *
      * @param provider the name of the provider
      * @return true if the provider exists and is enabled
      *
      * @throws IllegalArgumentException if provider is null
-     * @throws SecurityException if no suitable permission is present
      */
     public boolean isProviderEnabled(String provider) {
+        // STOPSHIP: finalize API version number in javadoc
         checkProvider(provider);
 
         try {
@@ -1610,7 +1616,7 @@
      * @hide
      */
     public boolean sendNiResponse(int notifId, int userResponse) {
-    	try {
+        try {
             return mService.sendNiResponse(notifId, userResponse);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in sendNiResponse: ", e);
diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java
index 9f321f3..98c7864 100644
--- a/location/java/android/location/SettingInjectorService.java
+++ b/location/java/android/location/SettingInjectorService.java
@@ -26,7 +26,7 @@
 import android.util.Log;
 
 /**
- * Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
+ * Dynamically specifies the enabled status of a preference injected into
  * the list of app settings displayed by the system settings app
  * <p/>
  * For use only by apps that are included in the system image, for preferences that affect multiple
@@ -71,13 +71,12 @@
  * </ul>
  *
  * To ensure a good user experience, your {@link android.app.Application#onCreate()},
- * {@link #onGetSummary()}, and {@link #onGetEnabled()} methods must all be fast. If any are slow,
- * it can delay the display of settings values for other apps as well. Note further that all are
- * called on your app's UI thread.
+ * and {@link #onGetEnabled()} methods must all be fast. If either is slow,
+ * it can delay the display of settings values for other apps as well. Note further that these
+ * methods are called on your app's UI thread.
  * <p/>
  * For compactness, only one copy of a given setting should be injected. If each account has a
- * distinct value for the setting, then the {@link #onGetSummary()} value should represent a summary
- * of the state across all of the accounts and {@code settingsActivity} should display the value for
+ * distinct value for the setting, then only {@code settingsActivity} should display the value for
  * each account.
  */
 public abstract class SettingInjectorService extends Service {
@@ -109,14 +108,6 @@
             "android.location.InjectedSettingChanged";
 
     /**
-     * Name of the bundle key for the string specifying the summary for the setting (e.g., "ON" or
-     * "OFF").
-     *
-     * @hide
-     */
-    public static final String SUMMARY_KEY = "summary";
-
-    /**
      * Name of the bundle key for the string specifying whether the setting is currently enabled.
      *
      * @hide
@@ -160,42 +151,31 @@
 
     private void onHandleIntent(Intent intent) {
 
-        String summary;
-        try {
-            summary = onGetSummary();
-        } catch (RuntimeException e) {
-            // Exception. Send status anyway, so that settings injector can immediately start
-            // loading the status of the next setting.
-            sendStatus(intent, null, true);
-            throw e;
-        }
-
         boolean enabled;
         try {
             enabled = onGetEnabled();
         } catch (RuntimeException e) {
             // Exception. Send status anyway, so that settings injector can immediately start
             // loading the status of the next setting.
-            sendStatus(intent, summary, true);
+            sendStatus(intent, true);
             throw e;
         }
 
-        sendStatus(intent, summary, enabled);
+        sendStatus(intent, enabled);
     }
 
     /**
-     * Send the summary and enabled values back to the caller via the messenger encoded in the
+     * Send the enabled values back to the caller via the messenger encoded in the
      * intent.
      */
-    private void sendStatus(Intent intent, String summary, boolean enabled) {
+    private void sendStatus(Intent intent, boolean enabled) {
         Message message = Message.obtain();
         Bundle bundle = new Bundle();
-        bundle.putString(SUMMARY_KEY, summary);
         bundle.putBoolean(ENABLED_KEY, enabled);
         message.setData(bundle);
 
         if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, mName + ": received " + intent + ", summary=" + summary
+            Log.d(TAG, mName + ": received " + intent
                     + ", enabled=" + enabled + ", sending message: " + message);
         }
 
@@ -208,13 +188,18 @@
     }
 
     /**
-     * Returns the {@link android.preference.Preference#getSummary()} value (allowed to be null or
-     * empty). Should not perform unpredictably-long operations such as network access--see the
-     * running-time comments in the class-level javadoc.
+     * This method is no longer called, because status values are no longer shown for any injected
+     * setting.
      *
-     * @return the {@link android.preference.Preference#getSummary()} value
+     * @return ignored
+     *
+     * @deprecated not called any more
      */
-    protected abstract String onGetSummary();
+    @Deprecated
+    protected String onGetSummary() {
+        // Do not delete until no callers have @Override annotations for this method
+        return null;
+    }
 
     /**
      * Returns the {@link android.preference.Preference#isEnabled()} value. Should not perform
diff --git a/media/java/android/media/IMediaController.aidl b/media/java/android/media/session/IMediaController.aidl
similarity index 92%
rename from media/java/android/media/IMediaController.aidl
rename to media/java/android/media/session/IMediaController.aidl
index fc3525a..8ca0e45 100644
--- a/media/java/android/media/IMediaController.aidl
+++ b/media/java/android/media/session/IMediaController.aidl
@@ -13,10 +13,10 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
 import android.content.Intent;
-import android.media.IMediaControllerCallback;
+import android.media.session.IMediaControllerCallback;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.view.KeyEvent;
diff --git a/media/java/android/media/IMediaControllerCallback.aidl b/media/java/android/media/session/IMediaControllerCallback.aidl
similarity index 96%
rename from media/java/android/media/IMediaControllerCallback.aidl
rename to media/java/android/media/session/IMediaControllerCallback.aidl
index b54d0cf..3aa0ee4 100644
--- a/media/java/android/media/IMediaControllerCallback.aidl
+++ b/media/java/android/media/session/IMediaControllerCallback.aidl
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
 import android.os.Bundle;
 
diff --git a/media/java/android/media/IMediaSession.aidl b/media/java/android/media/session/IMediaSession.aidl
similarity index 92%
rename from media/java/android/media/IMediaSession.aidl
rename to media/java/android/media/session/IMediaSession.aidl
index ed71d78..19f7092 100644
--- a/media/java/android/media/IMediaSession.aidl
+++ b/media/java/android/media/session/IMediaSession.aidl
@@ -13,9 +13,9 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
-import android.media.IMediaController;
+import android.media.session.IMediaController;
 import android.os.Bundle;
 
 /**
diff --git a/media/java/android/media/IMediaSessionCallback.aidl b/media/java/android/media/session/IMediaSessionCallback.aidl
similarity index 96%
rename from media/java/android/media/IMediaSessionCallback.aidl
rename to media/java/android/media/session/IMediaSessionCallback.aidl
index 3aaf925..eb5f222 100644
--- a/media/java/android/media/IMediaSessionCallback.aidl
+++ b/media/java/android/media/session/IMediaSessionCallback.aidl
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
 import android.content.Intent;
 import android.os.Bundle;
diff --git a/media/java/android/media/IMediaSessionManager.aidl b/media/java/android/media/session/IMediaSessionManager.aidl
similarity index 86%
rename from media/java/android/media/IMediaSessionManager.aidl
rename to media/java/android/media/session/IMediaSessionManager.aidl
index 8bc0c3b..0b4328e 100644
--- a/media/java/android/media/IMediaSessionManager.aidl
+++ b/media/java/android/media/session/IMediaSessionManager.aidl
@@ -13,10 +13,10 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
-import android.media.IMediaSession;
-import android.media.IMediaSessionCallback;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
 import android.os.Bundle;
 
 /**
diff --git a/media/java/android/media/MediaController.java b/media/java/android/media/session/MediaController.java
similarity index 97%
rename from media/java/android/media/MediaController.java
rename to media/java/android/media/session/MediaController.java
index 1e99942..09de859 100644
--- a/media/java/android/media/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -14,9 +14,13 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
 import android.content.Intent;
+import android.media.session.IMediaController;
+import android.media.session.IMediaControllerCallback;
+import android.media.MediaMetadataRetriever;
+import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
diff --git a/media/java/android/media/MediaSession.java b/media/java/android/media/session/MediaSession.java
similarity index 97%
rename from media/java/android/media/MediaSession.java
rename to media/java/android/media/session/MediaSession.java
index 5e5c9fa..1f1533b 100644
--- a/media/java/android/media/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
 import android.content.Intent;
-import android.media.IMediaSession;
+import android.media.session.IMediaController;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
+import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
diff --git a/media/java/android/media/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
similarity index 96%
rename from media/java/android/media/MediaSessionManager.java
rename to media/java/android/media/session/MediaSessionManager.java
index 90f0071..e3f2d9c 100644
--- a/media/java/android/media/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
 import android.content.Context;
+import android.media.session.IMediaSessionManager;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
diff --git a/media/java/android/media/MediaSessionToken.aidl b/media/java/android/media/session/MediaSessionToken.aidl
similarity index 95%
rename from media/java/android/media/MediaSessionToken.aidl
rename to media/java/android/media/session/MediaSessionToken.aidl
index e2f1abc..5812682 100644
--- a/media/java/android/media/MediaSessionToken.aidl
+++ b/media/java/android/media/session/MediaSessionToken.aidl
@@ -13,6 +13,6 @@
 ** limitations under the License.
 */
 
-package android.media;
+package android.media.session;
 
 parcelable MediaSessionToken;
diff --git a/media/java/android/media/MediaSessionToken.java b/media/java/android/media/session/MediaSessionToken.java
similarity index 95%
rename from media/java/android/media/MediaSessionToken.java
rename to media/java/android/media/session/MediaSessionToken.java
index 885fda3..dbb4964 100644
--- a/media/java/android/media/MediaSessionToken.java
+++ b/media/java/android/media/session/MediaSessionToken.java
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.session;
 
+import android.media.session.IMediaController;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 51fccd4..35327c0 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -61,8 +61,7 @@
     $(call include-path-for, libhardware)/hardware \
     system/media/camera/include \
     $(PV_INCLUDES) \
-    $(JNI_H_INCLUDE) \
-    $(call include-path-for, corecg graphics)
+    $(JNI_H_INCLUDE)
 
 LOCAL_CFLAGS +=
 
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 3ce483d..b2fb2df 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -112,12 +112,35 @@
     mLooper->registerHandler(this);
 }
 
-JMediaCodec::~JMediaCodec() {
+void JMediaCodec::release() {
     if (mCodec != NULL) {
         mCodec->release();
         mCodec.clear();
     }
 
+    if (mLooper != NULL) {
+        mLooper->unregisterHandler(id());
+        mLooper->stop();
+        mLooper.clear();
+    }
+}
+
+JMediaCodec::~JMediaCodec() {
+    if (mCodec != NULL || mLooper != NULL) {
+        /* MediaCodec and looper should have been released explicitly already
+         * in setMediaCodec() (see comments in setMediaCodec()).
+         *
+         * Otherwise JMediaCodec::~JMediaCodec() might be called from within the
+         * message handler, doing release() there risks deadlock as MediaCodec::
+         * release() post synchronous message to the same looper.
+         *
+         * Print a warning and try to proceed with releasing.
+         */
+        ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()...");
+        release();
+        ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec().");
+    }
+
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
     env->DeleteWeakGlobalRef(mObject);
@@ -432,6 +455,12 @@
         codec->incStrong(thiz);
     }
     if (old != NULL) {
+        /* release MediaCodec and stop the looper now before decStrong.
+         * otherwise JMediaCodec::~JMediaCodec() could be called from within
+         * its message handler, doing release() from there will deadlock
+         * (as MediaCodec::release() post synchronous message to the same looper)
+         */
+        old->release();
         old->decStrong(thiz);
     }
     env->SetLongField(thiz, gFields.context, (jlong)codec.get());
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 53254c9..2f2ea96 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -42,6 +42,7 @@
     status_t initCheck() const;
 
     void registerSelf();
+    void release();
 
     status_t configure(
             const sp<AMessage> &format,
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index f17209f..f3a7ff7 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -21,7 +21,7 @@
 #include <assert.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
-#include <core/SkBitmap.h>
+#include <SkBitmap.h>
 #include <media/IMediaHTTPService.h>
 #include <media/mediametadataretriever.h>
 #include <private/media/VideoFrame.h>
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 6be7fdd..76e8346 100644
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -35,7 +35,6 @@
     $(TOP)/frameworks/base/media/libstagefright/include \
     $(TOP)/frameworks/base/media/libstagefright/rtsp \
     $(JNI_H_INCLUDE) \
-    $(call include-path-for, corecg graphics) \
     $(TOP)/frameworks/native/include/media/editor \
     $(TOP)/frameworks/base/core/jni/mediaeditor \
     $(TOP)/frameworks/av/libvideoeditor/vss/inc \
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index 8c76421..eb1a589 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -85,8 +85,8 @@
         super.setUp();
         mMockProvider = EasyMock.createMock(IContentProvider.class);
         mMediaInserter = new MediaInserter(mMockProvider,
-		mPackageName, TEST_BUFFER_SIZE);
-	mPackageName = getInstrumentation().getContext().getPackageName();
+        mPackageName, TEST_BUFFER_SIZE);
+        mPackageName = getInstrumentation().getContext().getPackageName();
         mFilesCounter = 0;
         mAudioCounter = 0;
         mVideoCounter = 0;
@@ -224,19 +224,19 @@
     @SmallTest
     public void testInsertContentsWithDifferentSizePerContentType() throws Exception {
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sFilesUri),
+        MediaUriMatcher.expectMediaUri(sFilesUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(1);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sAudioUri),
+        MediaUriMatcher.expectMediaUri(sAudioUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(2);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sVideoUri),
+        MediaUriMatcher.expectMediaUri(sVideoUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(3);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sImagesUri),
+        MediaUriMatcher.expectMediaUri(sImagesUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(4);
         EasyMock.replay(mMockProvider);
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk
index ad874c8..95ae33b 100644
--- a/media/tests/omxjpegdecoder/Android.mk
+++ b/media/tests/omxjpegdecoder/Android.mk
@@ -34,11 +34,6 @@
 
 LOCAL_C_INCLUDES := \
     $(TOP)/external/jpeg \
-    $(TOP)/external/skia/include/config \
-    $(TOP)/external/skia/include/core \
-    $(TOP)/external/skia/include/images \
-    $(TOP)/external/skia/include/utils \
-    $(TOP)/external/skia/include/effects \
     $(TOP)/frameworks/base/media/libstagefright \
     $(TOP)/frameworks/base/include/ \
     $(TOP)/frameworks/base/ \
diff --git a/media/tests/omxjpegdecoder/StreamSource.h b/media/tests/omxjpegdecoder/StreamSource.h
index 6c34cbd..9807385 100644
--- a/media/tests/omxjpegdecoder/StreamSource.h
+++ b/media/tests/omxjpegdecoder/StreamSource.h
@@ -20,7 +20,7 @@
 
 #include <stdio.h>
 
-#include <core/SkStream.h>
+#include <SkStream.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaErrors.h>
 #include <utils/threads.h>
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 8b333e7..3154030 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -23,7 +23,6 @@
     libskia
 
 LOCAL_C_INCLUDES += \
-	external/skia/include/core \
 	frameworks/base/native/include \
 	frameworks/base/core/jni/android/graphics
 
diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java
index b93557d..cf09c58 100644
--- a/opengl/java/android/opengl/EGL14.java
+++ b/opengl/java/android/opengl/EGL14.java
@@ -160,6 +160,13 @@
         int display_id
     );
 
+    /**
+     * {@hide}
+     */
+    public static native EGLDisplay eglGetDisplay(
+        long display_id
+    );
+
     // C function EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor )
 
     public static native boolean eglInitialize(
@@ -324,7 +331,7 @@
     );
 
     // C function EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list )
-
+    // TODO Deprecate the below method
     public static native EGLSurface eglCreatePbufferFromClientBuffer(
         EGLDisplay dpy,
         int buftype,
@@ -333,6 +340,18 @@
         int[] attrib_list,
         int offset
     );
+    // TODO Unhide the below method
+    /**
+     * {@hide}
+     */
+    public static native EGLSurface eglCreatePbufferFromClientBuffer(
+        EGLDisplay dpy,
+        int buftype,
+        long buffer,
+        EGLConfig config,
+        int[] attrib_list,
+        int offset
+    );
 
     // C function EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value )
 
diff --git a/opengl/java/android/opengl/EGLConfig.java b/opengl/java/android/opengl/EGLConfig.java
index a7a6bbb..9881070 100644
--- a/opengl/java/android/opengl/EGLConfig.java
+++ b/opengl/java/android/opengl/EGLConfig.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLConfig extends EGLObjectHandle {
-    private EGLConfig(int handle) {
+    private EGLConfig(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLConfig)) return false;
 
         EGLConfig that = (EGLConfig) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/EGLContext.java b/opengl/java/android/opengl/EGLContext.java
index c93bd6e..f791e7e 100644
--- a/opengl/java/android/opengl/EGLContext.java
+++ b/opengl/java/android/opengl/EGLContext.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLContext extends EGLObjectHandle {
-    private EGLContext(int handle) {
+    private EGLContext(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLContext)) return false;
 
         EGLContext that = (EGLContext) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/EGLDisplay.java b/opengl/java/android/opengl/EGLDisplay.java
index 5b8043a..e872761 100644
--- a/opengl/java/android/opengl/EGLDisplay.java
+++ b/opengl/java/android/opengl/EGLDisplay.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLDisplay extends EGLObjectHandle {
-    private EGLDisplay(int handle) {
+    private EGLDisplay(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLDisplay)) return false;
 
         EGLDisplay that = (EGLDisplay) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/EGLObjectHandle.java b/opengl/java/android/opengl/EGLObjectHandle.java
index d2710de..f961eb7 100644
--- a/opengl/java/android/opengl/EGLObjectHandle.java
+++ b/opengl/java/android/opengl/EGLObjectHandle.java
@@ -22,12 +22,30 @@
  *
  */
 public abstract class EGLObjectHandle {
-    private final int mHandle;
+    private final long mHandle;
 
+    /**
+     * @deprecated Use {@link #EGLObjectHandle(long)} instead. Handles
+     *     on 64 bit platforms will be wider than java ints.
+     */
+    @Deprecated
     protected EGLObjectHandle(int handle) {
         mHandle = handle;
     }
-
+    protected EGLObjectHandle(long handle) {
+        mHandle = handle;
+    }
+    /**
+     * @deprecated Use {@link #getNativeHandle()} instead. Handles on
+     *     64 bit platforms will be wider than java ints.
+     */
+    @Deprecated
+    public int getHandle() {
+        if ((mHandle & 0xffffffffL) != mHandle) {
+            throw new UnsupportedOperationException();
+        }
+        return (int)mHandle;
+    }
     /**
      * Returns the native handle of the wrapped EGL object. This handle can be
      * cast to the corresponding native type on the native side.
@@ -36,12 +54,17 @@
      *
      * @return the native handle of the wrapped EGL object.
      */
-    public int getHandle() {
+    public long getNativeHandle() {
         return mHandle;
     }
-
     @Override
     public int hashCode() {
-        return getHandle();
+        /*
+         * Based on the algorithm suggested in
+         * http://developer.android.com/reference/java/lang/Object.html
+         */
+        int result = 17;
+        result = 31 * result + (int) (mHandle ^ (mHandle >>> 32));
+        return result;
     }
 }
diff --git a/opengl/java/android/opengl/EGLSurface.java b/opengl/java/android/opengl/EGLSurface.java
index c379dc9..c200f72 100644
--- a/opengl/java/android/opengl/EGLSurface.java
+++ b/opengl/java/android/opengl/EGLSurface.java
@@ -22,7 +22,7 @@
  *
  */
 public class EGLSurface extends EGLObjectHandle {
-    private EGLSurface(int handle) {
+    private EGLSurface(long handle) {
         super(handle);
     }
 
@@ -32,6 +32,6 @@
         if (!(o instanceof EGLSurface)) return false;
 
         EGLSurface that = (EGLSurface) o;
-        return getHandle() == that.getHandle();
+        return getNativeHandle() == that.getNativeHandle();
     }
 }
diff --git a/opengl/java/android/opengl/GLES10.java b/opengl/java/android/opengl/GLES10.java
index db52b82..fed84d5 100644
--- a/opengl/java/android/opengl/GLES10.java
+++ b/opengl/java/android/opengl/GLES10.java
@@ -262,7 +262,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
 
     private static Buffer _colorPointer;
diff --git a/opengl/java/android/opengl/GLES10Ext.java b/opengl/java/android/opengl/GLES10Ext.java
index 81fc59e..3dc26eb 100644
--- a/opengl/java/android/opengl/GLES10Ext.java
+++ b/opengl/java/android/opengl/GLES10Ext.java
@@ -22,7 +22,7 @@
 public class GLES10Ext {
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
     
     // C function GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent )
diff --git a/opengl/java/android/opengl/GLES11.java b/opengl/java/android/opengl/GLES11.java
index 1ca179b..bb69bba 100644
--- a/opengl/java/android/opengl/GLES11.java
+++ b/opengl/java/android/opengl/GLES11.java
@@ -147,7 +147,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
 
     private static Buffer _pointSizePointerOES;
diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java
index 484439a..04d1b5d 100644
--- a/opengl/java/android/opengl/GLES11Ext.java
+++ b/opengl/java/android/opengl/GLES11Ext.java
@@ -132,7 +132,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
     
     private static final int GL_BYTE = GLES10.GL_BYTE;
diff --git a/opengl/java/android/opengl/GLES30.java b/opengl/java/android/opengl/GLES30.java
index 9164849..342ffa4 100644
--- a/opengl/java/android/opengl/GLES30.java
+++ b/opengl/java/android/opengl/GLES30.java
@@ -864,13 +864,13 @@
         int buffer
     );
 
-	// C function void glTransformFeedbackVaryings ( GLuint program, GLsizei count, const GLchar *varyings, GLenum bufferMode )
+    // C function void glTransformFeedbackVaryings ( GLuint program, GLsizei count, const GLchar *varyings, GLenum bufferMode )
 
-	public static native void glTransformFeedbackVaryings(
+    public static native void glTransformFeedbackVaryings(
         int program,
         String[] varyings,
         int bufferMode
-	);
+    );
 
     // C function void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name )
 
@@ -1245,14 +1245,14 @@
         int size
     );
 
-	// C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
+    // C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
 
-	public static native void glGetUniformIndices(
+    public static native void glGetUniformIndices(
         int program,
         String[] uniformNames,
         int[] uniformIndices,
         int uniformIndicesOffset
-	);
+    );
 
     // C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
 
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 6b23be9..d4c0c80 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -39,7 +39,7 @@
 
     native private static void _nativeClassInit();
     static {
-	_nativeClassInit();
+        _nativeClassInit();
     }
 
     Buffer _colorPointer = null;
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
index 1f2b5fb..5b08674 100644
--- a/packages/Keyguard/Android.mk
+++ b/packages/Keyguard/Android.mk
@@ -16,7 +16,8 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files) \
+                   $(call all-proto-files-under,src)
 
 LOCAL_PACKAGE_NAME := Keyguard
 
@@ -26,6 +27,9 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
+
 include $(BUILD_PACKAGE)
 
 #include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
new file mode 100644
index 0000000..ebd0a64
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+    and the security view. -->
+<com.android.keyguard.KeyguardSimpleHostView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_host_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.android.keyguard.KeyguardSecurityContainer
+        android:id="@+id/keyguard_security_container"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/keyguard_security_height"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:padding="0dp"
+        android:layout_gravity="center">
+        <com.android.keyguard.KeyguardSecurityViewFlipper
+            android:id="@+id/view_flipper"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:paddingTop="@dimen/keyguard_security_view_margin"
+            android:gravity="center">
+        </com.android.keyguard.KeyguardSecurityViewFlipper>
+    </com.android.keyguard.KeyguardSecurityContainer>
+
+</com.android.keyguard.KeyguardSimpleHostView>
+
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index fd4cf78..ebe678e 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -27,7 +27,7 @@
     <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"የይለፍ ቃል ለመተየብ ንካ"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ለመክፈት የይለፍ ቃል ተይብ"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ለመክፈት ፒን ተይብ"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ PIN ኮድ።"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ ፒን  ኮድ።"</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"ለመክፈት፣ምናሌ ተጫን ከዛ 0"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"የመጨረሻውን  የገጽ ክፈት ሙከራዎችን አልፏል"</string>
     <string name="keyguard_charged" msgid="3272223906073492454">"ባትሪ ሞልቷል"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 7ac94bd..1e79ee4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -1051,9 +1051,6 @@
     }
 
     private void enableUserSelectorIfNecessary() {
-        if (!UserManager.supportsMultipleUsers()) {
-            return; // device doesn't support multi-user mode
-        }
         final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         if (um == null) {
             Throwable t = new Throwable();
@@ -1063,61 +1060,53 @@
         }
 
         // if there are multiple users, we need to enable to multi-user switcher
-        final List<UserInfo> users = um.getUsers(true);
-        if (users == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "list of users is null.", t);
+        if (!um.isUserSwitcherEnabled()) {
             return;
         }
 
         final View multiUserView = findViewById(R.id.keyguard_user_selector);
         if (multiUserView == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "can't find user_selector in layout.", t);
+            if (DEBUG) Log.d(TAG, "can't find user_selector in layout.");
             return;
         }
 
-        if (users.size() > 1) {
-            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
-                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
-                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
-                mKeyguardMultiUserSelectorView.addUsers(users);
-                UserSwitcherCallback callback = new UserSwitcherCallback() {
-                    @Override
-                    public void hideSecurityView(int duration) {
-                        getSecurityContainer().animate().alpha(0).setDuration(duration);
-                    }
-
-                    @Override
-                    public void showSecurityView() {
-                        getSecurityContainer().setAlpha(1.0f);
-                    }
-
-                    @Override
-                    public void showUnlockHint() {
-                        if (getSecurityContainer() != null) {
-                            getSecurityContainer().showUsabilityHint();
-                        }
-                    }
-
-                    @Override
-                    public void userActivity() {
-                        if (mViewMediatorCallback != null) {
-                            mViewMediatorCallback.userActivity();
-                        }
-                    }
-                };
-                mKeyguardMultiUserSelectorView.setCallback(callback);
-            } else {
-                Throwable t = new Throwable();
-                t.fillInStackTrace();
-                if (multiUserView == null) {
-                    Log.e(TAG, "could not find the user_selector.", t);
-                } else {
-                    Log.e(TAG, "user_selector is the wrong type.", t);
+        if (multiUserView instanceof KeyguardMultiUserSelectorView) {
+            mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
+            mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
+            mKeyguardMultiUserSelectorView.addUsers(um.getUsers(true));
+            UserSwitcherCallback callback = new UserSwitcherCallback() {
+                @Override
+                public void hideSecurityView(int duration) {
+                    getSecurityContainer().animate().alpha(0).setDuration(duration);
                 }
+
+                @Override
+                public void showSecurityView() {
+                    getSecurityContainer().setAlpha(1.0f);
+                }
+
+                @Override
+                public void showUnlockHint() {
+                    if (getSecurityContainer() != null) {
+                        getSecurityContainer().showUsabilityHint();
+                    }
+                }
+
+                @Override
+                public void userActivity() {
+                    if (mViewMediatorCallback != null) {
+                        mViewMediatorCallback.userActivity();
+                    }
+                }
+            };
+            mKeyguardMultiUserSelectorView.setCallback(callback);
+        } else {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            if (multiUserView == null) {
+                Log.e(TAG, "could not find the user_selector.", t);
+            } else {
+                Log.e(TAG, "user_selector is the wrong type.", t);
             }
         }
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
index 7975d8e..06815e1 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
@@ -76,11 +76,13 @@
         Collections.sort(users, mOrderAddedComparator);
 
         for (UserInfo user: users) {
-            KeyguardMultiUserAvatar uv = createAndAddUser(user);
-            if (user.id == activeUser.id) {
-                mActiveUserAvatar = uv;
+            if (user.supportsSwitchTo()) {
+                KeyguardMultiUserAvatar uv = createAndAddUser(user);
+                if (user.id == activeUser.id) {
+                    mActiveUserAvatar = uv;
+                }
+                uv.setActive(false, false, null);
             }
-            uv.setActive(false, false, null);
         }
         mActiveUserAvatar.lockPressed(true);
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 43165eb..8738288 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -21,11 +21,11 @@
 
 import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.analytics.KeyguardAnalytics;
 
 import org.xmlpull.v1.XmlPullParser;
 
 import android.app.ActivityManager;
-import android.appwidget.AppWidgetManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
@@ -71,10 +71,12 @@
 
     // Timeout used for keypresses
     static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
+    private static final boolean ENABLE_SIMPLE_KEYGUARD = false;
 
     private final Context mContext;
     private final ViewManager mViewManager;
     private final KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+    private final KeyguardAnalytics.Callback mAnalyticsCallback;
 
     private WindowManager.LayoutParams mWindowLayoutParams;
     private boolean mNeedsInput = false;
@@ -106,11 +108,12 @@
      */
     public KeyguardViewManager(Context context, ViewManager viewManager,
             KeyguardViewMediator.ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils, KeyguardAnalytics.Callback analyticsCallback) {
         mContext = context;
         mViewManager = viewManager;
         mViewMediatorCallback = callback;
         mLockPatternUtils = lockPatternUtils;
+        mAnalyticsCallback = analyticsCallback;
     }
 
     /**
@@ -119,6 +122,9 @@
      */
     public synchronized void show(Bundle options) {
         if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
+        if (mAnalyticsCallback != null) {
+            mAnalyticsCallback.onShow();
+        }
 
         boolean enableScreenRotation = shouldEnableScreenRotation();
 
@@ -261,6 +267,15 @@
             }
             return super.dispatchKeyEvent(event);
         }
+
+        @Override
+        public boolean dispatchTouchEvent(MotionEvent ev) {
+            boolean result = false;
+            if (mAnalyticsCallback != null) {
+                result = mAnalyticsCallback.onTouchEvent(ev, getWidth(), getHeight()) || result;
+            }
+            return super.dispatchTouchEvent(ev) || result;
+        }
     }
 
     SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
@@ -312,7 +327,7 @@
         if (force || mKeyguardView == null) {
             mKeyguardHost.setCustomBackground(null);
             mKeyguardHost.removeAllViews();
-            int layout = allowNotificationsOnSecureKeyguard()
+            int layout = (allowNotificationsOnSecureKeyguard() && ENABLE_SIMPLE_KEYGUARD)
                     ? R.layout.keyguard_simple_host_view
                     : R.layout.keyguard_host_view;
             if (mCurrentLayout != layout) {
@@ -472,6 +487,9 @@
                 Slog.w(TAG, "Exception calling onShown():", e);
             }
         }
+        if (mAnalyticsCallback != null) {
+            mAnalyticsCallback.onScreenOn();
+        }
     }
 
     public synchronized void verifyUnlock() {
@@ -486,6 +504,10 @@
     public synchronized void hide() {
         if (DEBUG) Log.d(TAG, "hide()");
 
+        if (mAnalyticsCallback != null) {
+            mAnalyticsCallback.onHide();
+        }
+
         if (mKeyguardHost != null) {
             mKeyguardHost.setVisibility(View.GONE);
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index e0ee4e0..31e806c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -19,6 +19,7 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardShowCallback;
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+import static com.android.keyguard.analytics.KeyguardAnalytics.SessionTypeAdapter;
 
 import android.app.Activity;
 import android.app.ActivityManagerNative;
@@ -33,6 +34,7 @@
 import android.content.IntentFilter;
 import android.media.AudioManager;
 import android.media.SoundPool;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -54,6 +56,10 @@
 
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.analytics.Session;
+import com.android.keyguard.analytics.KeyguardAnalytics;
+
+import java.io.File;
 
 
 /**
@@ -100,6 +106,7 @@
 public class KeyguardViewMediator {
     private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
     final static boolean DEBUG = false;
+    private static final boolean ENABLE_ANALYTICS = Build.IS_DEBUGGABLE;
     private final static boolean DBG_WAKE = false;
 
     private final static String TAG = "KeyguardViewMediator";
@@ -161,6 +168,11 @@
      */
     private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false;
 
+    /**
+     * Secure setting whether analytics are collected on the keyguard.
+     */
+    private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
+
     /** The stream type that the lock sounds are tied to. */
     private int mMasterStreamType;
 
@@ -194,6 +206,8 @@
 
     private KeyguardViewManager mKeyguardViewManager;
 
+    private final KeyguardAnalytics mKeyguardAnalytics;
+
     // these are protected by synchronized (this)
 
     /**
@@ -528,12 +542,25 @@
                 && !mLockPatternUtils.isLockScreenDisabled();
 
         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-
-        mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
-                mLockPatternUtils);
-
         final ContentResolver cr = mContext.getContentResolver();
 
+        if (ENABLE_ANALYTICS && !LockPatternUtils.isSafeModeEnabled() &&
+                Settings.Secure.getInt(cr, KEYGUARD_ANALYTICS_SETTING, 0) == 1) {
+            mKeyguardAnalytics = new KeyguardAnalytics(context, new SessionTypeAdapter() {
+
+                @Override
+                public int getSessionType() {
+                    return mLockPatternUtils.isSecure() ? Session.TYPE_KEYGUARD_SECURE
+                            : Session.TYPE_KEYGUARD_INSECURE;
+                }
+            }, new File(mContext.getCacheDir(), "keyguard_analytics.bin"));
+        } else {
+            mKeyguardAnalytics = null;
+        }
+        mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
+                mLockPatternUtils,
+                mKeyguardAnalytics != null ? mKeyguardAnalytics.getCallback() : null);
+
         mScreenOn = mPM.isScreenOn();
 
         mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
@@ -631,6 +658,9 @@
             } else {
                 doKeyguardLocked(null);
             }
+            if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) {
+                mKeyguardAnalytics.getCallback().onScreenOff();
+            }
         }
         KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why);
     }
@@ -704,7 +734,7 @@
 
     private void maybeSendUserPresentBroadcast() {
         if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()
-                && mUserManager.getUsers(true).size() == 1) {
+                && !mUserManager.isUserSwitcherEnabled()) {
             // Lock screen is disabled because the user has set the preference to "None".
             // In this case, send out ACTION_USER_PRESENT here instead of in
             // handleKeyguardDone()
@@ -869,6 +899,9 @@
                 updateActivityLockScreenState();
                 adjustStatusBarLocked();
             }
+            if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) {
+                mKeyguardAnalytics.getCallback().onSetHidden(isHidden);
+            }
         }
     }
 
@@ -940,7 +973,7 @@
             return;
         }
 
-        if (mUserManager.getUsers(true).size() < 2
+        if (!mUserManager.isUserSwitcherEnabled()
                 && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
             return;
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java b/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java
new file mode 100644
index 0000000..55750cc
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard.analytics;
+
+import com.google.protobuf.nano.CodedOutputByteBufferNano;
+import com.google.protobuf.nano.MessageNano;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.AsyncTask;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Tracks sessions, touch and sensor events in Keyguard.
+ *
+ * A session starts when the user is presented with the Keyguard and ends when the Keyguard is no
+ * longer visible to the user.
+ */
+public class KeyguardAnalytics implements SensorEventListener {
+
+    private static final boolean DEBUG = false;
+    private static final String TAG = "KeyguardAnalytics";
+    private static final long TIMEOUT_MILLIS = 11000; // 11 seconds.
+
+    private static final int[] SENSORS = new int[] {
+            Sensor.TYPE_ACCELEROMETER,
+            Sensor.TYPE_GYROSCOPE,
+            Sensor.TYPE_PROXIMITY,
+            Sensor.TYPE_LIGHT,
+            Sensor.TYPE_ROTATION_VECTOR,
+    };
+
+    private Session mCurrentSession = null;
+    // Err on the side of caution, so logging is not started after a crash even tough the screen
+    // is off.
+    private boolean mScreenOn = false;
+    private boolean mHidden = false;
+
+    private final SensorManager mSensorManager;
+    private final SessionTypeAdapter mSessionTypeAdapter;
+    private final File mAnalyticsFile;
+
+    public KeyguardAnalytics(Context context, SessionTypeAdapter sessionTypeAdapter,
+            File analyticsFile) {
+        mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+        mSessionTypeAdapter = sessionTypeAdapter;
+        mAnalyticsFile = analyticsFile;
+    }
+
+    public Callback getCallback() {
+        return mCallback;
+    }
+
+    public interface Callback {
+        public void onShow();
+        public void onHide();
+        public void onScreenOn();
+        public void onScreenOff();
+        public boolean onTouchEvent(MotionEvent ev, int width, int height);
+        public void onSetHidden(boolean hidden);
+    }
+
+    public interface SessionTypeAdapter {
+        public int getSessionType();
+    }
+
+    private void sessionEntrypoint() {
+        if (mCurrentSession == null && mScreenOn && !mHidden) {
+            onSessionStart();
+        }
+    }
+
+    private void sessionExitpoint(int result) {
+        if (mCurrentSession != null) {
+            onSessionEnd(result);
+        }
+    }
+
+    private void onSessionStart() {
+        int type = mSessionTypeAdapter.getSessionType();
+        mCurrentSession = new Session(System.currentTimeMillis(), System.nanoTime(), type);
+        if (type == Session.TYPE_KEYGUARD_SECURE) {
+            mCurrentSession.setRedactTouchEvents();
+        }
+        for (int sensorType : SENSORS) {
+            Sensor s = mSensorManager.getDefaultSensor(sensorType);
+            if (s != null) {
+                mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
+            }
+        }
+        if (DEBUG) {
+            Log.d(TAG, "onSessionStart()");
+        }
+    }
+
+    private void onSessionEnd(int result) {
+        if (DEBUG) {
+            Log.d(TAG, String.format("onSessionEnd(success=%d)", result));
+        }
+        mSensorManager.unregisterListener(this);
+
+        Session session = mCurrentSession;
+        mCurrentSession = null;
+
+        session.end(System.currentTimeMillis(), result);
+        queueSession(session);
+    }
+
+    private void queueSession(final Session currentSession) {
+        if (DEBUG) {
+            Log.i(TAG, "Saving session.");
+        }
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                try {
+                    byte[] b = writeDelimitedProto(currentSession.toProto());
+                    OutputStream os = new FileOutputStream(mAnalyticsFile, true /* append */);
+                    if (DEBUG) {
+                        Log.d(TAG, String.format("Serialized size: %d kB.", b.length / 1024));
+                    }
+                    try {
+                        os.write(b);
+                        os.flush();
+                    } finally {
+                        try {
+                            os.close();
+                        } catch (IOException e) {
+                            Log.e(TAG, "Exception while closing file", e);
+                        }
+                    }
+                } catch (IOException e) {
+                    Log.e(TAG, "Exception while writing file", e);
+                }
+                return null;
+            }
+
+            private byte[] writeDelimitedProto(MessageNano proto)
+                    throws IOException {
+                byte[] result = new byte[CodedOutputByteBufferNano.computeMessageSizeNoTag(proto)];
+                CodedOutputByteBufferNano ob = CodedOutputByteBufferNano.newInstance(result);
+                ob.writeMessageNoTag(proto);
+                ob.checkNoSpaceLeft();
+                return result;
+            }
+        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+    }
+
+    @Override
+    public synchronized void onSensorChanged(SensorEvent event) {
+        if (false) {
+            Log.v(TAG, String.format(
+                    "onSensorChanged(name=%s, values[0]=%f)",
+                    event.sensor.getName(), event.values[0]));
+        }
+        if (mCurrentSession != null) {
+            mCurrentSession.addSensorEvent(event, System.nanoTime());
+            enforceTimeout();
+        }
+    }
+
+    private void enforceTimeout() {
+        if (System.currentTimeMillis() - mCurrentSession.getStartTimestampMillis()
+                > TIMEOUT_MILLIS) {
+            onSessionEnd(Session.RESULT_UNKNOWN);
+            if (DEBUG) {
+                Log.i(TAG, "Analytics timed out.");
+            }
+        }
+    }
+
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    }
+
+    private final Callback mCallback = new Callback() {
+        @Override
+        public void onShow() {
+            if (DEBUG) {
+                Log.d(TAG, "onShow()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                sessionEntrypoint();
+            }
+        }
+
+        @Override
+        public void onHide() {
+            if (DEBUG) {
+                Log.d(TAG, "onHide()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                sessionExitpoint(Session.RESULT_SUCCESS);
+            }
+        }
+
+        @Override
+        public void onScreenOn() {
+            if (DEBUG) {
+                Log.d(TAG, "onScreenOn()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                mScreenOn = true;
+                sessionEntrypoint();
+            }
+        }
+
+        @Override
+        public void onScreenOff() {
+            if (DEBUG) {
+                Log.d(TAG, "onScreenOff()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                mScreenOn = false;
+                sessionExitpoint(Session.RESULT_FAILURE);
+            }
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev, int width, int height) {
+            if (DEBUG) {
+                Log.v(TAG, "onTouchEvent(ev.action="
+                        + MotionEvent.actionToString(ev.getAction()) + ")");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.addMotionEvent(ev);
+                    mCurrentSession.setTouchArea(width, height);
+                    enforceTimeout();
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public void onSetHidden(boolean hidden) {
+            synchronized (KeyguardAnalytics.this) {
+                if (hidden != mHidden) {
+                    if (DEBUG) {
+                        Log.d(TAG, "onSetHidden(" + hidden + ")");
+                    }
+                    mHidden = hidden;
+                    if (hidden) {
+                        // Could have gone to camera on purpose / by falsing or an app could have
+                        // launched on top of the lockscreen.
+                        sessionExitpoint(Session.RESULT_UNKNOWN);
+                    } else {
+                        sessionEntrypoint();
+                    }
+                }
+            }
+        }
+    };
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java b/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java
new file mode 100644
index 0000000..e68f751
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard.analytics;
+
+import android.graphics.RectF;
+import android.util.FloatMath;
+import android.util.SparseArray;
+import android.view.MotionEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.TouchEvent.BoundingBox;
+
+/**
+ * Takes motion events and tracks the length and bounding box of each pointer gesture as well as
+ * the bounding box of the whole gesture.
+ */
+public class PointerTracker {
+    private SparseArray<Pointer> mPointerInfoMap = new SparseArray<Pointer>();
+    private RectF mTotalBoundingBox = new RectF();
+
+    public void addMotionEvent(MotionEvent ev) {
+        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            float x = ev.getX();
+            float y = ev.getY();
+            mTotalBoundingBox.set(x, y, x, y);
+        }
+        for (int i = 0; i < ev.getPointerCount(); i++) {
+            int id = ev.getPointerId(i);
+            Pointer pointer = getPointer(id);
+            float x = ev.getX(i);
+            float y = ev.getY(i);
+            boolean down = ev.getActionMasked() == MotionEvent.ACTION_DOWN
+                    || (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN
+                            && ev.getActionIndex() == i);
+            pointer.addPoint(x, y, down);
+            mTotalBoundingBox.union(x, y);
+        }
+    }
+
+    public float getPointerLength(int id) {
+        return getPointer(id).length;
+    }
+
+    public BoundingBox getBoundingBox() {
+        return boundingBoxFromRect(mTotalBoundingBox);
+    }
+
+    public BoundingBox getPointerBoundingBox(int id) {
+        return boundingBoxFromRect(getPointer(id).boundingBox);
+    }
+
+    private BoundingBox boundingBoxFromRect(RectF f) {
+        BoundingBox bb = new BoundingBox();
+        bb.setHeight(f.height());
+        bb.setWidth(f.width());
+        return bb;
+    }
+
+    private Pointer getPointer(int id) {
+        Pointer p = mPointerInfoMap.get(id);
+        if (p == null) {
+            p = new Pointer();
+            mPointerInfoMap.put(id, p);
+        }
+        return p;
+    }
+
+    private static class Pointer {
+        public float length;
+        public final RectF boundingBox = new RectF();
+
+        private float mLastX;
+        private float mLastY;
+
+        public void addPoint(float x, float y, boolean down) {
+            float deltaX;
+            float deltaY;
+            if (down) {
+                boundingBox.set(x, y, x, y);
+                length = 0f;
+                deltaX = 0;
+                deltaY = 0;
+            } else {
+                deltaX = x - mLastX;
+                deltaY = y - mLastY;
+            }
+            mLastX = x;
+            mLastY = y;
+            length += FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY);
+            boundingBox.union(x, y);
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/Session.java b/packages/Keyguard/src/com/android/keyguard/analytics/Session.java
new file mode 100644
index 0000000..05f9165
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/Session.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard.analytics;
+
+import android.os.Build;
+import android.util.Slog;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+
+import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.SensorEvent;
+import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.TouchEvent;
+
+/**
+ * Records data about one keyguard session.
+ *
+ * The recorded data contains start and end of the session, whether it unlocked the device
+ * successfully, sensor data and touch data.
+ *
+ * If the keyguard is secure, the recorded touch data will correlate or contain the user pattern or
+ * PIN. If this is not desired, the touch coordinates can be redacted before serialization.
+ */
+public class Session {
+
+    private static final String TAG = "KeyguardAnalytics";
+    private static final boolean DEBUG = false;
+
+    /**
+     * The user has failed to unlock the device in this session.
+     */
+    public static final int RESULT_FAILURE = KeyguardAnalyticsProtos.Session.FAILURE;
+    /**
+     * The user has succeeded in unlocking the device in this session.
+     */
+    public static final int RESULT_SUCCESS = KeyguardAnalyticsProtos.Session.SUCCESS;
+
+    /**
+     * It is unknown how the session with the keyguard ended.
+     */
+    public static final int RESULT_UNKNOWN = KeyguardAnalyticsProtos.Session.UNKNOWN;
+
+    /**
+     * This session took place on an insecure keyguard.
+     */
+    public static final int TYPE_KEYGUARD_INSECURE
+            = KeyguardAnalyticsProtos.Session.KEYGUARD_INSECURE;
+
+    /**
+     * This session took place on an secure keyguard.
+     */
+    public static final int TYPE_KEYGUARD_SECURE
+            = KeyguardAnalyticsProtos.Session.KEYGUARD_SECURE;
+
+    /**
+     * This session took place during a fake wake up of the device.
+     */
+    public static final int TYPE_RANDOM_WAKEUP = KeyguardAnalyticsProtos.Session.RANDOM_WAKEUP;
+
+
+    private final PointerTracker mPointerTracker = new PointerTracker();
+
+    private final long mStartTimestampMillis;
+    private final long mStartSystemTimeNanos;
+    private final int mType;
+
+    private boolean mRedactTouchEvents;
+    private ArrayList<TouchEvent> mMotionEvents = new ArrayList<TouchEvent>(200);
+    private ArrayList<SensorEvent> mSensorEvents = new ArrayList<SensorEvent>(600);
+    private int mTouchAreaHeight;
+    private int mTouchAreaWidth;
+
+    private long mEndTimestampMillis;
+    private int mResult;
+    private boolean mEnded;
+
+    public Session(long startTimestampMillis, long startSystemTimeNanos, int type) {
+        mStartTimestampMillis = startTimestampMillis;
+        mStartSystemTimeNanos = startSystemTimeNanos;
+        mType = type;
+    }
+
+    public void end(long endTimestampMillis, int result) {
+        mEnded = true;
+        mEndTimestampMillis = endTimestampMillis;
+        mResult = result;
+    }
+
+    public void addMotionEvent(MotionEvent motionEvent) {
+        if (mEnded) {
+            return;
+        }
+        mPointerTracker.addMotionEvent(motionEvent);
+        mMotionEvents.add(protoFromMotionEvent(motionEvent));
+    }
+
+    public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) {
+        if (mEnded) {
+            return;
+        }
+        SensorEvent event = protoFromSensorEvent(eventOrig, systemTimeNanos);
+        mSensorEvents.add(event);
+        if (DEBUG) {
+            Slog.v(TAG, String.format("addSensorEvent(name=%s, values[0]=%f",
+                    event.getType(), event.values[0]));
+        }
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("Session{");
+        sb.append("mType=").append(mType);
+        sb.append(", mStartTimestampMillis=").append(mStartTimestampMillis);
+        sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos);
+        sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis);
+        sb.append(", mResult=").append(mResult);
+        sb.append(", mRedactTouchEvents=").append(mRedactTouchEvents);
+        sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight);
+        sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth);
+        sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]");
+        sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]");
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public KeyguardAnalyticsProtos.Session toProto() {
+        KeyguardAnalyticsProtos.Session proto = new KeyguardAnalyticsProtos.Session();
+        proto.setStartTimestampMillis(mStartTimestampMillis);
+        proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis);
+        proto.setBuild(Build.FINGERPRINT);
+        proto.setResult(mResult);
+        proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents);
+        proto.touchEvents = mMotionEvents.toArray(proto.touchEvents);
+        proto.setTouchAreaWidth(mTouchAreaWidth);
+        proto.setTouchAreaHeight(mTouchAreaHeight);
+        proto.setType(mType);
+        if (mRedactTouchEvents) {
+            redactTouchEvents(proto.touchEvents);
+        }
+        return proto;
+    }
+
+    private void redactTouchEvents(TouchEvent[] touchEvents) {
+        for (int i = 0; i < touchEvents.length; i++) {
+            TouchEvent t = touchEvents[i];
+            for (int j = 0; j < t.pointers.length; j++) {
+                TouchEvent.Pointer p = t.pointers[j];
+                p.clearX();
+                p.clearY();
+            }
+            t.setRedacted(true);
+        }
+    }
+
+    private SensorEvent protoFromSensorEvent(android.hardware.SensorEvent ev, long sysTimeNanos) {
+        SensorEvent proto = new SensorEvent();
+        proto.setType(ev.sensor.getType());
+        proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
+        proto.setTimestamp(ev.timestamp);
+        proto.values = ev.values.clone();
+        return proto;
+    }
+
+    private TouchEvent protoFromMotionEvent(MotionEvent ev) {
+        int count = ev.getPointerCount();
+        TouchEvent proto = new TouchEvent();
+        proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos);
+        proto.setAction(ev.getActionMasked());
+        proto.setActionIndex(ev.getActionIndex());
+        proto.pointers = new TouchEvent.Pointer[count];
+        for (int i = 0; i < count; i++) {
+            TouchEvent.Pointer p = new TouchEvent.Pointer();
+            p.setX(ev.getX(i));
+            p.setY(ev.getY(i));
+            p.setSize(ev.getSize(i));
+            p.setPressure(ev.getPressure(i));
+            p.setId(ev.getPointerId(i));
+            proto.pointers[i] = p;
+            if ((ev.getActionMasked() == MotionEvent.ACTION_POINTER_UP && ev.getActionIndex() == i)
+                    || ev.getActionMasked() == MotionEvent.ACTION_UP) {
+                p.boundingBox = mPointerTracker.getPointerBoundingBox(p.getId());
+                p.setLength(mPointerTracker.getPointerLength(p.getId()));
+            }
+        }
+        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+            proto.boundingBox = mPointerTracker.getBoundingBox();
+        }
+        return proto;
+    }
+
+    /**
+     * Discards the x / y coordinates of the touch events on serialization. Retained are the
+     * size of the individual and overall bounding boxes and the length of each pointer's gesture.
+     */
+    public void setRedactTouchEvents() {
+        mRedactTouchEvents = true;
+    }
+
+    public void setTouchArea(int width, int height) {
+        mTouchAreaWidth = width;
+        mTouchAreaHeight = height;
+    }
+
+    public long getStartTimestampMillis() {
+        return mStartTimestampMillis;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto b/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto
new file mode 100644
index 0000000..68b1590
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto
@@ -0,0 +1,102 @@
+/*
+ * 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
+ */
+
+syntax = "proto2";
+
+package keyguard;
+
+option java_package = "com.android.keyguard.analytics";
+option java_outer_classname = "KeyguardAnalyticsProtos";
+
+message Session {
+    message TouchEvent {
+        message BoundingBox {
+            optional float width = 1;
+            optional float height = 2;
+        }
+
+        enum Action {
+            // Keep in sync with MotionEvent.
+            DOWN = 0;
+            UP = 1;
+            MOVE = 2;
+            CANCEL = 3;
+            OUTSIDE = 4;
+            POINTER_DOWN = 5;
+            POINTER_UP = 6;
+        }
+
+        message Pointer {
+            optional float x = 1;
+            optional float y = 2;
+            optional float size = 3;
+            optional float pressure = 4;
+            optional int32 id = 5;
+            optional float length = 6;
+            // Bounding box of the pointer. Only set on UP or POINTER_UP event of this pointer.
+            optional BoundingBox boundingBox = 7;
+        }
+
+        optional uint64 timeOffsetNanos = 1;
+        optional Action action = 2;
+        optional int32 actionIndex = 3;
+        repeated Pointer pointers = 4;
+        /* If true, the the x / y coordinates of the touch events were redacted. Retained are the
+           size of the individual and overall bounding boxes and the length of each pointer's
+           gesture. */
+        optional bool redacted = 5;
+        // Bounding box of the whole gesture. Only set on UP event.
+        optional BoundingBox boundingBox = 6;
+    }
+
+    message SensorEvent {
+        enum Type {
+            ACCELEROMETER = 1;
+            GYROSCOPE = 4;
+            LIGHT = 5;
+            PROXIMITY = 8;
+            ROTATION_VECTOR = 11;
+        }
+
+        optional Type type = 1;
+        optional uint64 timeOffsetNanos = 2;
+        repeated float values = 3;
+        optional uint64 timestamp = 4;
+    }
+
+    enum Result {
+        FAILURE = 0;
+        SUCCESS = 1;
+        UNKNOWN = 2;
+    }
+
+    enum Type {
+        KEYGUARD_INSECURE = 0;
+        KEYGUARD_SECURE = 1;
+        RANDOM_WAKEUP = 2;
+    }
+
+    optional uint64 startTimestampMillis = 1;
+    optional uint64 durationMillis = 2;
+    optional string build = 3;
+    optional Result result = 4;
+    repeated TouchEvent touchEvents = 5;
+    repeated SensorEvent sensorEvents = 6;
+
+    optional int32 touchAreaWidth = 9;
+    optional int32 touchAreaHeight = 10;
+    optional Type type = 11;
+}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 69f7152..59b486f 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -183,4 +183,10 @@
     <!-- Default for Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE -->
     <integer name="def_wifi_scan_always_available">0</integer>
 
+    <!-- Default for Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
+    <integer name="def_lock_screen_show_notifications">1</integer>
+
+    <!-- Default for Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, 1==on -->
+    <integer name="def_heads_up_enabled">1</integer>
+
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index f316d88..55d7def 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -69,7 +69,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 98;
+    private static final int DATABASE_VERSION = 100;
 
     private Context mContext;
     private int mUserHandle;
@@ -1556,6 +1556,42 @@
             upgradeVersion = 98;
         }
 
+        if (upgradeVersion == 98) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                            R.integer.def_lock_screen_show_notifications);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 99;
+        }
+
+        if (upgradeVersion == 99) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                            R.integer.def_heads_up_enabled);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 100;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/anim/heads_up_exit.xml b/packages/SystemUI/res/anim/heads_up_exit.xml
index 05c144a..2cad8f6 100644
--- a/packages/SystemUI/res/anim/heads_up_exit.xml
+++ b/packages/SystemUI/res/anim/heads_up_exit.xml
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         >
-    <scale
-        android:interpolator="@android:interpolator/accelerate_quad"
-        android:fromXScale="1.0" android:toXScale="0.7"
-        android:fromYScale="1.0" android:toYScale="0.7"
-        android:pivotX="50%" android:pivotY="50%"
-        android:duration="@android:integer/config_shortAnimTime" />
-    <alpha 
+    <translate
+            android:interpolator="@android:interpolator/overshoot"
+            android:fromYDelta="0" android:toYDelta="-50%"
+            android:duration="@android:integer/config_shortAnimTime" />
+    <alpha
         android:interpolator="@android:interpolator/accelerate_quad"
         android:fromAlpha="1.0" android:toAlpha="0.0"
         android:duration="@android:integer/config_shortAnimTime" />
diff --git a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
deleted file mode 100644
index 5b6778e..0000000
--- a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/anim/ease_out_interpolator.xml
-**
-** Copyright 2007, 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.
-*/
--->
-
-<decelerateInterpolator 
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:factor="10.0" />
diff --git a/packages/SystemUI/res/anim/lights_out_in.xml b/packages/SystemUI/res/anim/lights_out_in.xml
deleted file mode 100644
index f76a452..0000000
--- a/packages/SystemUI/res/anim/lights_out_in.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromYDelta="-100%p" android:toYDelta="0"
-        android:duration="@android:integer/config_mediumAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/lights_out_out.xml b/packages/SystemUI/res/anim/lights_out_out.xml
deleted file mode 100644
index 610ac7a..0000000
--- a/packages/SystemUI/res/anim/lights_out_out.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toYDelta="-100%p" android:fromYDelta="0" 
-        android:duration="@android:integer/config_mediumAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:toAlpha="0.5" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/notification_dnd_on.xml b/packages/SystemUI/res/anim/notification_dnd_on.xml
deleted file mode 100644
index 309943b..0000000
--- a/packages/SystemUI/res/anim/notification_dnd_on.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toXDelta="100%p" android:fromXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
diff --git a/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png
deleted file mode 100644
index 3b952d0..0000000
--- a/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-hdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..267e7ba
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..fa23e85
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..aa8635c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png
deleted file mode 100644
index a0ab991..0000000
--- a/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-mdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..db51f6b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..b0185a5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..949ab10
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..b30cf15
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
index 6002cfb..31eb8f7 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
index 586a738..c76d0e1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png
deleted file mode 100644
index 42e5593..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-xhdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..8d22ce2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..7f7cb63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..abdeb3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png
deleted file mode 100644
index 586a738..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-xxhdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..29fb50f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..afe85b4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..5e5053f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-sw600dp/heads_up.xml b/packages/SystemUI/res/layout-sw600dp/heads_up.xml
new file mode 100644
index 0000000..71f7c21
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/heads_up.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+<com.android.systemui.statusbar.policy.HeadsUpNotificationView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    >
+    <FrameLayout
+        android:id="@+id/content_holder"
+        android:layout_height="wrap_content"
+        android:layout_width="@dimen/notification_panel_width"
+        android:layout_marginStart="@dimen/notification_panel_margin_left"
+        android:background="@drawable/heads_up_window_bg"
+        />
+</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
diff --git a/packages/SystemUI/res/layout/heads_up.xml b/packages/SystemUI/res/layout/heads_up.xml
index 564dc51..3a58b84 100644
--- a/packages/SystemUI/res/layout/heads_up.xml
+++ b/packages/SystemUI/res/layout/heads_up.xml
@@ -17,25 +17,11 @@
 ** limitations under the License.
 */
 -->
-
-<!--    android:background="@drawable/status_bar_closed_default_background" -->
 <com.android.systemui.statusbar.policy.HeadsUpNotificationView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:orientation="vertical"
-    >
-    <FrameLayout
-            android:layout_height="wrap_content"
-            android:layout_width="@dimen/notification_panel_width"
-            android:id="@+id/content_slider"
-            android:layout_marginStart="@dimen/notification_panel_margin_left"
-            >
-        <FrameLayout
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:id="@+id/content_holder"
-                android:background="@drawable/heads_up_window_bg"
-                />
-    </FrameLayout>
-</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_height="wrap_content"
+        android:layout_width="@dimen/notification_panel_width"
+        android:id="@+id/content_holder"
+        android:layout_marginStart="@dimen/notification_panel_margin_left"
+        android:background="@drawable/notification_panel_bg"
+        />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index eb66908..ea6be1b 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -62,7 +62,11 @@
                 android:src="@drawable/stat_notify_more"
                 android:visibility="gone"
                 />
-
+            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/modeIcon"
+                android:layout_width="@dimen/status_bar_icon_size"
+                android:layout_height="match_parent"
+                android:visibility="gone"
+                />
             <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 1693e01..56c1f4e 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -58,6 +58,12 @@
             android:layout_height="@dimen/notification_panel_header_height"
             />
 
+        <com.android.systemui.statusbar.phone.ZenModeView
+            android:id="@+id/zenmode"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+
         <TextView
             android:id="@+id/emergency_calls_only"
             android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 9aa7cfd..25c516b 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -15,7 +15,7 @@
 ** limitations under the License.
 -->
 
-<LinearLayout
+<com.android.systemui.statusbar.phone.PanelHeaderView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
     android:id="@+id/header"
@@ -106,4 +106,4 @@
             android:contentDescription="@string/accessibility_notifications_button"
             />
     </FrameLayout>
-</LinearLayout>
+</com.android.systemui.statusbar.phone.PanelHeaderView>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index b5c24d7..033e56d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -72,7 +72,7 @@
     <string name="use_mtp_button_title" msgid="4333504413563023626">"ต่อเชื่อมเป็นโปรแกรมเล่นสื่อ (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"ต่อเชื่อมเป็นกล้องถ่ายรูป (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"ติดตั้งแอปพลิเคชัน Android File Transfer ของ Mac"</string>
-    <string name="accessibility_back" msgid="567011538994429120">"ย้อนกลับ"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"กลับ"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"หน้าแรก"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"เมนู"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"แอปพลิเคชันล่าสุด"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e6b2b8b..65cd231 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -79,6 +79,9 @@
     <!-- Height of a large notification in the status bar -->
     <dimen name="notification_max_height">256dp</dimen>
 
+    <!-- Height of a medium notification in the status bar -->
+    <dimen name="notification_mid_height">128dp</dimen>
+
     <!-- Height of a small notification in the status bar plus glow, padding, etc -->
     <dimen name="notification_row_min_height">70dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7ff52de..fb11743 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -96,7 +96,7 @@
     protected static final boolean ENABLE_HEADS_UP = true;
     // scores above this threshold should be displayed in heads up mode.
     protected static final int INTERRUPTION_THRESHOLD = 11;
-    protected static final String SETTING_HEADS_UP = "heads_up_enabled";
+    protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
 
     // Should match the value in PhoneWindowManager
     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
@@ -104,6 +104,9 @@
     public static final int EXPANDED_LEAVE_ALONE = -10000;
     public static final int EXPANDED_FULL_OPEN = -10001;
 
+    private static final String EXTRA_INTERCEPT = "android.intercept";
+    private static final float INTERCEPTED_ALPHA = .2f;
+
     protected CommandQueue mCommandQueue;
     protected IStatusBarService mBarService;
     protected H mHandler = createHandler();
@@ -128,6 +131,7 @@
     protected int mLayoutDirection = -1; // invalid
     private Locale mLocale;
     protected boolean mUseHeadsUp = false;
+    protected boolean mHeadsUpTicker = false;
 
     protected IDreamManager mDreamManager;
     PowerManager mPowerManager;
@@ -155,6 +159,8 @@
 
     private RecentsComponent mRecents;
 
+    protected int mZenMode;
+
     public IStatusBarService getStatusBarService() {
         return mBarService;
     }
@@ -163,7 +169,7 @@
         return mDeviceProvisioned;
     }
 
-    private final ContentObserver mProvisioningObserver = new ContentObserver(mHandler) {
+    protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
         @Override
         public void onChange(boolean selfChange) {
             final boolean provisioned = 0 != Settings.Global.getInt(
@@ -172,6 +178,9 @@
                 mDeviceProvisioned = provisioned;
                 updateNotificationIcons();
             }
+            final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+            setZenMode(mode);
         }
     };
 
@@ -239,10 +248,13 @@
                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
-        mProvisioningObserver.onChange(false); // set up
+        mSettingsObserver.onChange(false); // set up
         mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
-                mProvisioningObserver);
+                mSettingsObserver);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
+                mSettingsObserver);
 
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
@@ -683,6 +695,13 @@
         StatusBarNotification sbn = entry.notification;
         RemoteViews contentView = sbn.getNotification().contentView;
         RemoteViews bigContentView = sbn.getNotification().bigContentView;
+
+        if (isHeadsUp) {
+            maxHeight =
+                    mContext.getResources().getDimensionPixelSize(R.dimen.notification_mid_height);
+            bigContentView = sbn.getNotification().headsUpContentView;
+        }
+
         if (contentView == null) {
             return false;
         }
@@ -980,6 +999,7 @@
         if (DEBUG) {
             Log.d(TAG, "addNotificationViews: added at " + pos);
         }
+        updateInterceptedState(entry);
         updateExpansionStates();
         updateNotificationIcons();
     }
@@ -1010,6 +1030,35 @@
         }
     }
 
+    protected void setZenMode(int mode) {
+        if (!isDeviceProvisioned()) return;
+        final boolean change = mZenMode != mode;
+        mZenMode = mode;
+        final int N = mNotificationData.size();
+        for (int i = 0; i < N; i++) {
+            final NotificationData.Entry entry = mNotificationData.get(i);
+            if (change && !shouldIntercept()) {
+                entry.notification.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false);
+            }
+            updateInterceptedState(entry);
+        }
+        updateNotificationIcons();
+    }
+
+    private boolean shouldIntercept() {
+        return mZenMode == Settings.Global.ZEN_MODE_LIMITED
+                || mZenMode == Settings.Global.ZEN_MODE_FULL;
+    }
+
+    protected boolean shouldIntercept(Notification n) {
+        return shouldIntercept() && n.extras.getBoolean(EXTRA_INTERCEPT);
+    }
+
+    private void updateInterceptedState(NotificationData.Entry entry) {
+        final boolean intercepted = shouldIntercept(entry.notification.getNotification());
+        entry.row.findViewById(R.id.container).setAlpha(intercepted ? INTERCEPTED_ALPHA : 1);
+    }
+
     protected abstract void haltTicker();
     protected abstract void setAreThereNotifications();
     protected abstract void updateNotificationIcons();
@@ -1038,6 +1087,8 @@
         final RemoteViews contentView = notification.getNotification().contentView;
         final RemoteViews oldBigContentView = oldNotification.getNotification().bigContentView;
         final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        final RemoteViews oldHeadsUpContentView = oldNotification.getNotification().headsUpContentView;
+        final RemoteViews headsUpContentView = notification.getNotification().headsUpContentView;
         final Notification oldPublicNotification = oldNotification.getNotification().publicVersion;
         final RemoteViews oldPublicContentView = oldPublicNotification != null
                 ? oldPublicNotification.contentView : null;
@@ -1077,6 +1128,13 @@
                     && oldBigContentView.getPackage() != null
                     && oldBigContentView.getPackage().equals(bigContentView.getPackage())
                     && oldBigContentView.getLayoutId() == bigContentView.getLayoutId());
+        boolean headsUpContentsUnchanged =
+                (oldHeadsUpContentView == null && headsUpContentView == null)
+                || ((oldHeadsUpContentView != null && headsUpContentView != null)
+                    && headsUpContentView.getPackage() != null
+                    && oldHeadsUpContentView.getPackage() != null
+                    && oldHeadsUpContentView.getPackage().equals(headsUpContentView.getPackage())
+                    && oldHeadsUpContentView.getLayoutId() == headsUpContentView.getLayoutId());
         boolean publicUnchanged  =
                 (oldPublicContentView == null && publicContentView == null)
                 || ((oldPublicContentView != null && publicContentView != null)
@@ -1095,7 +1153,7 @@
                 && !TextUtils.equals(notification.getNotification().tickerText,
                         oldEntry.notification.getNotification().tickerText);
         boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
-        if (contentsUnchanged && bigContentsUnchanged && publicUnchanged
+        if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged
                 && (orderUnchanged || isTopAnyway)) {
             if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
             oldEntry.notification = notification;
@@ -1179,7 +1237,9 @@
     private void updateNotificationViews(NotificationData.Entry entry,
             StatusBarNotification notification, boolean isHeadsUp) {
         final RemoteViews contentView = notification.getNotification().contentView;
-        final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        final RemoteViews bigContentView = isHeadsUp
+                ? notification.getNotification().headsUpContentView
+                : notification.getNotification().bigContentView;
         final Notification publicVersion = notification.getNotification().publicVersion;
         final RemoteViews publicContentView = publicVersion != null ? publicVersion.contentView
                 : null;
@@ -1202,6 +1262,7 @@
         } else {
             entry.content.setOnClickListener(null);
         }
+        updateInterceptedState(entry);
     }
 
     protected void notifyHeadsUpScreenOn(boolean screenOn) {
@@ -1219,11 +1280,12 @@
                 || notification.vibrate != null;
         boolean isHighPriority = sbn.getScore() >= INTERRUPTION_THRESHOLD;
         boolean isFullscreen = notification.fullScreenIntent != null;
+        boolean hasTicker = mHeadsUpTicker && !TextUtils.isEmpty(notification.tickerText);
         boolean isAllowed = notification.extras.getInt(Notification.EXTRA_AS_HEADS_UP,
                 Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER;
 
         final KeyguardTouchDelegate keyguard = KeyguardTouchDelegate.getInstance(mContext);
-        boolean interrupt = (isFullscreen || (isHighPriority && isNoisy))
+        boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker)))
                 && isAllowed
                 && mPowerManager.isScreenOn()
                 && !keyguard.isShowingAndNotHidden()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 4427466..b9a59dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -71,9 +71,9 @@
             final StatusBarNotification na = a.notification;
             final StatusBarNotification nb = b.notification;
             int d = na.getScore() - nb.getScore();
-	    if (a.interruption != b.interruption) {
-	      return a.interruption ? 1 : -1;
-	    } else if (d != 0) {
+            if (a.interruption != b.interruption) {
+                return a.interruption ? 1 : -1;
+            } else if (d != 0) {
                 return d;
             } else {
                 return (int) (na.getNotification().when - nb.getNotification().when);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6be6d4d..237b7f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.view.MotionEvent;
@@ -56,6 +57,17 @@
         mHandleBar = resources.getDrawable(R.drawable.status_bar_close);
         mHandleBarHeight = resources.getDimensionPixelSize(R.dimen.close_handle_height);
         mHandleView = findViewById(R.id.handle);
+        PanelHeaderView header = (PanelHeaderView) findViewById(R.id.header);
+        ZenModeView zenModeView = (ZenModeView) findViewById(R.id.zenmode);
+        zenModeView.setAdapter(new ZenModeViewAdapter(mContext) {
+            @Override
+            public void configure() {
+                if (mStatusBar != null) {
+                    mStatusBar.startSettingsActivity(Settings.ACTION_ZEN_MODE_SETTINGS);
+                }
+            }
+        });
+        header.setZenModeView(zenModeView);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java
new file mode 100644
index 0000000..a28324d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+
+public class PanelHeaderView extends LinearLayout {
+    private static final String TAG = "PanelHeaderView";
+    private static final boolean DEBUG = false;
+
+    private ZenModeView mZenModeView;
+
+    public PanelHeaderView(Context context) {
+        super(context);
+    }
+
+    public PanelHeaderView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setZenModeView(ZenModeView zmv) {
+        mZenModeView = zmv;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        final boolean rt = super.dispatchTouchEvent(ev);
+        if (DEBUG) logTouchEvent("dispatchTouchEvent", rt, ev);
+        if (mZenModeView != null) {
+            mZenModeView.dispatchExternalTouchEvent(ev);
+        }
+        return rt;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        final boolean rt = super.onInterceptTouchEvent(ev);
+        if (DEBUG) logTouchEvent("onInterceptTouchEvent", rt, ev);
+        return rt;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        boolean rt = super.onTouchEvent(event);
+        if (DEBUG) logTouchEvent("onTouchEvent", rt, event);
+        return true;
+    }
+
+    private void logTouchEvent(String method, boolean rt, MotionEvent ev) {
+        Log.d(TAG, method + " " + (rt ? "TRUE" : "FALSE") + " " + ev);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 2114991..6718de1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -189,6 +189,8 @@
     IconMerger mNotificationIcons;
     // [+>
     View mMoreIcon;
+    // mode indicator icon
+    ImageView mModeIcon;
 
     // expanded notifications
     NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -310,13 +312,17 @@
         @Override
         public void onChange(boolean selfChange) {
             boolean wasUsing = mUseHeadsUp;
-            mUseHeadsUp = ENABLE_HEADS_UP && 0 != Settings.Global.getInt(
-                    mContext.getContentResolver(), SETTING_HEADS_UP, 0);
+            mUseHeadsUp = ENABLE_HEADS_UP && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
+                    mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                    Settings.Global.HEADS_UP_OFF);
+            mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
+                    mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
             Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
             if (wasUsing != mUseHeadsUp) {
                 if (!mUseHeadsUp) {
                     Log.d(TAG, "dismissing any existing heads up notification on disable event");
-                    mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                    setHeadsUpVisibility(false);
+                    mHeadsUpNotificationView.setNotification(null);
                     removeHeadsUpView();
                 } else {
                     addHeadsUpView();
@@ -341,6 +347,20 @@
         }};
 
     @Override
+    public void setZenMode(int mode) {
+        super.setZenMode(mode);
+        if (mModeIcon == null) return;
+        if (!isDeviceProvisioned()) return;
+        final boolean limited = mode == Settings.Global.ZEN_MODE_LIMITED;
+        final boolean full = mode == Settings.Global.ZEN_MODE_FULL;
+        mModeIcon.setVisibility(full || limited ? View.VISIBLE : View.GONE);
+        final int icon = limited ? R.drawable.stat_sys_zen_limited : R.drawable.stat_sys_zen_full;
+        if (full || limited) {
+            mModeIcon.setImageResource(icon);
+        }
+    }
+
+    @Override
     public void start() {
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
@@ -352,11 +372,15 @@
 
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext);
+        mSettingsObserver.onChange(false); // set up
 
         mHeadsUpObserver.onChange(true); // set up
         if (ENABLE_HEADS_UP) {
             mContext.getContentResolver().registerContentObserver(
-                    Settings.Global.getUriFor(SETTING_HEADS_UP), true,
+                    Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
+                    mHeadsUpObserver);
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
                     mHeadsUpObserver);
         }
     }
@@ -455,6 +479,7 @@
         mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
         mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
         mNotificationIcons.setOverflowIndicator(mMoreIcon);
+        mModeIcon = (ImageView)mStatusBarView.findViewById(R.id.modeIcon);
         mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
         mTickerView = mStatusBarView.findViewById(R.id.ticker);
 
@@ -855,7 +880,6 @@
                 PixelFormat.TRANSLUCENT);
         lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
         lp.gravity = Gravity.TOP;
-        lp.y = getStatusBarHeight();
         lp.setTitle("Heads Up");
         lp.packageName = mContext.getPackageName();
         lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
@@ -909,41 +933,43 @@
         if (shadeEntry == null) {
             return;
         }
-        if (mUseHeadsUp && shouldInterrupt(notification)) {
-            if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
-            Entry interruptionCandidate = new Entry(key, notification, null);
-            ViewGroup holder = mHeadsUpNotificationView.getHolder();
-            if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
-                mInterruptingNotificationTime = System.currentTimeMillis();
-                mInterruptingNotificationEntry = interruptionCandidate;
-                shadeEntry.setInterruption();
+        if (!shouldIntercept(notification.getNotification())) {
+            if (mUseHeadsUp && shouldInterrupt(notification)) {
+                if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
+                Entry interruptionCandidate = new Entry(key, notification, null);
+                ViewGroup holder = mHeadsUpNotificationView.getHolder();
+                if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
+                    mInterruptingNotificationTime = System.currentTimeMillis();
+                    mInterruptingNotificationEntry = interruptionCandidate;
+                    shadeEntry.setInterruption();
 
-                // 1. Populate mHeadsUpNotificationView
-                mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
+                    // 1. Populate mHeadsUpNotificationView
+                    mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
 
-                // 2. Animate mHeadsUpNotificationView in
-                mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+                    // 2. Animate mHeadsUpNotificationView in
+                    mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
 
-                // 3. Set alarm to age the notification off
-                resetHeadsUpDecayTimer();
-            }
-        } else if (notification.getNotification().fullScreenIntent != null) {
-            // Stop screensaver if the notification has a full-screen intent.
-            // (like an incoming phone call)
-            awakenDreams();
+                    // 3. Set alarm to age the notification off
+                    resetHeadsUpDecayTimer();
+                }
+            } else if (notification.getNotification().fullScreenIntent != null) {
+                // Stop screensaver if the notification has a full-screen intent.
+                // (like an incoming phone call)
+                awakenDreams();
 
-            // not immersive & a full-screen alert should be shown
-            if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
-            try {
-                notification.getNotification().fullScreenIntent.send();
-            } catch (PendingIntent.CanceledException e) {
-            }
-        } else {
-            // usual case: status bar visible & not immersive
+                // not immersive & a full-screen alert should be shown
+                if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
+                try {
+                    notification.getNotification().fullScreenIntent.send();
+                } catch (PendingIntent.CanceledException e) {
+                }
+            } else {
+                // usual case: status bar visible & not immersive
 
-            // show the ticker if there isn't already a heads up
-            if (mInterruptingNotificationEntry == null) {
-                tick(null, notification, true);
+                // show the ticker if there isn't already a heads up
+                if (mInterruptingNotificationEntry == null) {
+                    tick(null, notification, true);
+                }
             }
         }
         addNotificationViews(shadeEntry);
@@ -1096,6 +1122,9 @@
                 // in "public" mode (atop a secure keyguard), secret notifs are totally hidden
                 continue;
             }
+            if (shouldIntercept(ent.notification.getNotification())) {
+                continue;
+            }
             toShow.add(ent.icon);
         }
 
@@ -2183,6 +2212,9 @@
         pw.println(windowStateToString(mStatusBarWindowState));
         pw.print("  mStatusBarMode=");
         pw.println(BarTransitions.modeToString(mStatusBarMode));
+        pw.print("  mZenMode=");
+        pw.println(Settings.Global.zenModeToString(mZenMode));
+        pw.print("  mUseHeadsUp=" + mUseHeadsUp);
         dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
         if (mNavigationBarView != null) {
             pw.print("  mNavigationBarWindowState=");
@@ -2710,6 +2742,12 @@
                 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
+    public void startSettingsActivity(String action) {
+        if (mQS != null) {
+            mQS.startSettingsActivity(action);
+        }
+    }
+
     private static class FastColorDrawable extends Drawable {
         private final int mColor;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 4d7ff5e..c1c8946 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -278,7 +278,7 @@
         mTilesSetUp = true;
     }
 
-    private void startSettingsActivity(String action) {
+    public void startSettingsActivity(String action) {
         Intent intent = new Intent(action);
         startSettingsActivity(intent);
     }
@@ -312,7 +312,7 @@
             public void onClick(View v) {
                 collapsePanels();
                 final UserManager um = UserManager.get(mContext);
-                if (um.getUsers(true).size() > 1) {
+                if (um.isUserSwitcherEnabled()) {
                     // Since keyguard and systemui were merged into the same process to save
                     // memory, they share the same Looper and graphics context.  As a result,
                     // there's no way to allow concurrent animation while keyguard inflates.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
new file mode 100644
index 0000000..c4d2cce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.URLSpan;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.PopupWindow;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.ZenModeView.Adapter.ExitCondition;
+
+public class ZenModeView extends RelativeLayout {
+    private static final String TAG = ZenModeView.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private static final Typeface CONDENSED =
+            Typeface.create("sans-serif-condensed", Typeface.NORMAL);
+    private static final int GRAY = 0xff999999; //TextAppearance.StatusBar.Expanded.Network
+    private static final int BACKGROUND = 0xff1d3741; //0x3333b5e5;
+    private static final long DURATION = new ValueAnimator().getDuration();
+    private static final long BOUNCE_DURATION = DURATION / 3;
+    private static final float BOUNCE_SCALE = 0.8f;
+    private static final float SETTINGS_ALPHA = 0.6f;
+
+    private static final String FULL_TEXT =
+            "You won't hear any calls, alarms or timers.";
+
+    private final Context mContext;
+    private final Paint mPathPaint;
+    private final TextView mHintText;
+    private final ModeSpinner mModeSpinner;
+    private final ImageView mCloseButton;
+    private final ImageView mSettingsButton;
+    private final Rect mLayoutRect = new Rect();
+    private final UntilPager mUntilPager;
+    private final AlarmWarning mAlarmWarning;
+
+    private float mDownY;
+    private int mDownBottom;
+    private boolean mPeekable = true;
+    private boolean mClosing;
+    private int mBottom;
+    private int mWidthSpec;
+    private Adapter mAdapter;
+
+    public ZenModeView(Context context) {
+        this(context, null);
+    }
+
+    public ZenModeView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        if (DEBUG) log("new %s()", getClass().getSimpleName());
+        mContext = context;
+
+        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPathPaint.setStyle(Paint.Style.STROKE);
+        mPathPaint.setColor(GRAY);
+        mPathPaint.setStrokeWidth(5);
+
+        final int iconSize = mContext.getResources()
+                .getDimensionPixelSize(com.android.internal.R.dimen.notification_large_icon_width);
+        final int topRowSize = iconSize * 2 / 3;
+
+        mCloseButton = new ImageView(mContext);
+        mCloseButton.setAlpha(0f);
+        mCloseButton.setImageDrawable(sd(closePath(topRowSize), topRowSize, mPathPaint));
+        addView(mCloseButton, new LayoutParams(topRowSize, topRowSize));
+        mCloseButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                bounce(v, null);
+                close();
+            }
+        });
+
+        mSettingsButton = new ImageView(mContext);
+        mSettingsButton.setAlpha(0f);
+        final int p = topRowSize / 7;
+        mSettingsButton.setPadding(p, p, p, p);
+        mSettingsButton.setImageResource(R.drawable.ic_notify_settings_normal);
+        LayoutParams lp = new LayoutParams(topRowSize, topRowSize);
+        lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+        addView(mSettingsButton, lp);
+        mSettingsButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mAdapter != null && mAdapter.getMode() == Adapter.MODE_LIMITED) {
+                    mAdapter.configure();
+                }
+                bounce(mSettingsButton, null);
+            }
+        });
+
+        mModeSpinner = new ModeSpinner(mContext);
+        mModeSpinner.setAlpha(0);
+        mModeSpinner.setEnabled(false);
+        mModeSpinner.setId(android.R.id.title);
+        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
+        lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
+        addView(mModeSpinner, lp);
+
+
+        mUntilPager = new UntilPager(mContext, mPathPaint, iconSize);
+        mUntilPager.setId(android.R.id.tabhost);
+        mUntilPager.setAlpha(0);
+        lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+        lp.addRule(BELOW, mModeSpinner.getId());
+        addView(mUntilPager, lp);
+
+        mAlarmWarning = new AlarmWarning(mContext);
+        mAlarmWarning.setAlpha(0);
+        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+        lp.addRule(CENTER_HORIZONTAL);
+        lp.addRule(BELOW, mUntilPager.getId());
+        addView(mAlarmWarning, lp);
+
+        mHintText = new TextView(mContext);
+        mHintText.setTypeface(CONDENSED);
+        mHintText.setText("Swipe down for Limited Interruptions");
+        mHintText.setGravity(Gravity.CENTER);
+        mHintText.setTextColor(GRAY);
+        addView(mHintText, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+    }
+
+    private boolean isApplicable() {
+        return mAdapter != null && mAdapter.isApplicable();
+    }
+
+    private void close() {
+        mClosing = true;
+        final int startBottom = mBottom;
+        final int max = mPeekable ? getExpandedBottom() : startBottom;
+        mHintText.animate().alpha(1).setUpdateListener(new AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                final float f = animation.getAnimatedFraction();
+                final int hintBottom = mHintText.getBottom();
+                setPeeked(hintBottom + (int)((1-f) * (startBottom - hintBottom)), max);
+                if (f == 1) {
+                    mPeekable = true;
+                    mClosing = false;
+                    mModeSpinner.updateState();
+                    if (mAdapter != null) {
+                        mAdapter.cancel();
+                    }
+                }
+            }
+        }).start();
+        mUntilPager.animate().alpha(0).start();
+        mAlarmWarning.animate().alpha(0).start();
+    }
+
+    public void setAdapter(Adapter adapter) {
+        mAdapter = adapter;
+        mAdapter.setCallbacks(new Adapter.Callbacks() {
+            @Override
+            public void onChanged() {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        updateState(true);
+                    }
+                });
+            }
+        });
+        updateState(false);
+    }
+
+    private void updateState(boolean animate) {
+        final boolean applicable = isApplicable();
+        setVisibility(applicable ? VISIBLE : GONE);
+        if (!applicable) {
+            return;
+        }
+        if (mAdapter != null && mAdapter.getMode() == Adapter.MODE_OFF && !mPeekable) {
+            close();
+        } else {
+            mModeSpinner.updateState();
+            mUntilPager.updateState();
+            mAlarmWarning.updateState(animate);
+            final float settingsAlpha = getSettingsButtonAlpha();
+            if (settingsAlpha != mSettingsButton.getAlpha()) {
+                if (animate) {
+                    mSettingsButton.animate().alpha(settingsAlpha).start();
+                } else {
+                    mSettingsButton.setAlpha(settingsAlpha);
+                }
+            }
+            if (mPeekable && mAdapter != null && mAdapter.getMode() != Adapter.MODE_OFF) {
+                if (DEBUG) log("panic expand!");
+                mPeekable = false;
+                mModeSpinner.setEnabled(true);
+                mBottom = getExpandedBottom();
+                setExpanded(1);
+            }
+        }
+    }
+
+    private float getSettingsButtonAlpha() {
+        final boolean full = mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
+        final boolean collapsed = mHintText.getAlpha() == 1;
+        return full || collapsed ? 0 : SETTINGS_ALPHA;
+    }
+
+    private static Path closePath(int size) {
+        final int pad = size / 4;
+        final Path p = new Path();
+        p.moveTo(pad, pad);
+        p.lineTo(size - pad, size - pad);
+        p.moveTo(size - pad, pad);
+        p.lineTo(pad, size - pad);
+        return p;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (DEBUG) log("onMeasure %s %s",
+                MeasureSpec.toString(widthMeasureSpec), MeasureSpec.toString(heightMeasureSpec));
+        final boolean widthExact = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
+
+        if (!widthExact || (widthMeasureSpec != mWidthSpec)) {
+            if (DEBUG) log("  super.onMeasure");
+            final int hms = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            super.onMeasure(widthMeasureSpec, hms);
+            mBottom = mPeekable ? mHintText.getMeasuredHeight() : getExpandedBottom();
+            mWidthSpec = widthMeasureSpec;
+        }
+        if (DEBUG) log("mBottom (OM) = " + mBottom);
+        setMeasuredDimension(getMeasuredWidth(), mBottom);
+        if (DEBUG) log("  mw=%s mh=%s",
+                toString(getMeasuredWidthAndState()), toString(getMeasuredHeightAndState()));
+    }
+
+    private static String toString(int sizeAndState) {
+        final int size = sizeAndState & MEASURED_SIZE_MASK;
+        final boolean tooSmall = (sizeAndState & MEASURED_STATE_TOO_SMALL) != 0;
+        return size + (tooSmall ? "TOO SMALL" : "");
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        mLayoutRect.set(left, top, right, bottom);
+        if (DEBUG) log("onLayout %s %s %dx%d", changed,
+                mLayoutRect.toShortString(), mLayoutRect.width(), mLayoutRect.height());
+        super.onLayout(changed, left, top, right, bottom);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        final boolean rt = super.dispatchTouchEvent(ev);
+        if (DEBUG) logTouchEvent("dispatchTouchEvent", rt, ev);
+        return rt;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        final boolean rt = super.onInterceptTouchEvent(ev);
+        if (DEBUG) logTouchEvent("onInterceptTouchEvent", rt, ev);
+        if (isApplicable()
+                && ev.getAction() == MotionEvent.ACTION_DOWN
+                && ev.getY() > mCloseButton.getBottom()
+                && mPeekable) {
+            return true;
+        }
+        return rt;
+    }
+
+    private static void logTouchEvent(String method, boolean rt, MotionEvent event) {
+        final String action = MotionEvent.actionToString(event.getAction());
+        Log.d(TAG, method + " " + (rt ? "TRUE" : "FALSE") + " " + action);
+    }
+
+    private int getExpandedBottom() {
+        int b = mModeSpinner.getMeasuredHeight() + mUntilPager.getMeasuredHeight();
+        if (mAlarmWarning.getAlpha() == 1) b += mAlarmWarning.getMeasuredHeight();
+        return b;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        boolean rt = super.onTouchEvent(event);
+        if (DEBUG) logTouchEvent("onTouchEvent", rt, event);
+        if (!isApplicable() || !mPeekable) {
+            return rt;
+        }
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            mDownY = event.getY();
+            if (DEBUG) log("  mDownY=" + mDownY);
+            mDownBottom = mBottom;
+            return true;
+        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
+            final float dy = event.getY() - mDownY;
+            setPeeked(mDownBottom + (int)dy, getExpandedBottom());
+        } else if (event.getAction() == MotionEvent.ACTION_UP
+                || event.getAction() == MotionEvent.ACTION_CANCEL) {
+            final float dy = event.getY() - mDownY;
+            setPeeked(mDownBottom + (int)dy, getExpandedBottom());
+            if (mPeekable) {
+                close();
+            }
+        }
+        return rt;
+    }
+
+    private void setPeeked(int peeked, int max) {
+        if (DEBUG) log("setPeeked=" + peeked);
+        final int min = mHintText.getBottom();
+        peeked = Math.max(min, Math.min(peeked, max));
+        if (mBottom == peeked) {
+            return;
+        }
+        if (peeked == max) {
+            mPeekable = false;
+            mModeSpinner.setEnabled(true);
+            if (mAdapter != null) {
+                mAdapter.setMode(Adapter.MODE_LIMITED);
+            }
+        }
+        if (peeked == min) {
+            mPeekable = true;
+            mModeSpinner.setEnabled(false);
+        }
+        if (DEBUG) log("  mBottom=" + peeked);
+        mBottom = peeked;
+        final float f = (peeked - min) / (float)(max - min);
+        setExpanded(f);
+        requestLayout();
+    }
+
+    private void setExpanded(float f) {
+        if (DEBUG) log("setExpanded " + f);
+        final int a = (int)(Color.alpha(BACKGROUND) * f);
+        setBackgroundColor(Color.argb(a,
+                Color.red(BACKGROUND), Color.green(BACKGROUND), Color.blue(BACKGROUND)));
+        mHintText.setAlpha(1 - f);
+        mCloseButton.setAlpha(f);
+        mModeSpinner.setAlpha(f);
+        mUntilPager.setAlpha(f);
+        mSettingsButton.setAlpha(f * getSettingsButtonAlpha());
+    }
+
+    private static void log(String msg, Object... args) {
+        Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
+    }
+
+    private static ShapeDrawable sd(Path p, int size, Paint pt) {
+        final ShapeDrawable sd = new ShapeDrawable(new PathShape(p, size, size));
+        sd.getPaint().set(pt);
+        sd.setIntrinsicHeight(size);
+        sd.setIntrinsicWidth(size);
+        return sd;
+    }
+
+    public void dispatchExternalTouchEvent(MotionEvent ev) {
+        if (isApplicable()) {
+            onTouchEvent(ev);
+        }
+    }
+
+    private static void bounce(final View v, final Runnable midBounce) {
+        v.animate().scaleX(BOUNCE_SCALE).scaleY(BOUNCE_SCALE).setDuration(DURATION / 3)
+            .setListener(new AnimatorListenerAdapter() {
+                private boolean mFired;
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mFired) {
+                        mFired = true;
+                        if (midBounce != null) {
+                            midBounce.run();
+                        }
+                        v.animate().scaleX(1).scaleY(1).setListener(null).start();
+                    }
+                }
+            }).start();
+    }
+
+    private final class UntilPager extends RelativeLayout {
+        private final ImageView mPrev;
+        private final ImageView mNext;
+        private final TextView mText1;
+        private final TextView mText2;
+
+        private TextView mText;
+
+        public UntilPager(Context context, Paint pathPaint, int iconSize) {
+            super(context);
+            mText1 = new TextView(mContext);
+            mText1.setTypeface(CONDENSED);
+            mText1.setTextColor(GRAY);
+            mText1.setGravity(Gravity.CENTER);
+            LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, iconSize);
+            addView(mText1, lp);
+            mText = mText1;
+
+            mText2 = new TextView(mContext);
+            mText2.setTypeface(CONDENSED);
+            mText2.setTextColor(GRAY);
+            mText2.setAlpha(0);
+            mText2.setGravity(Gravity.CENTER);
+            addView(mText2, lp);
+
+            lp = new LayoutParams(iconSize, iconSize);
+            final View v = new View(mContext);
+            v.setBackgroundColor(BACKGROUND);
+            addView(v, lp);
+            mPrev = new ImageView(mContext);
+            mPrev.setId(android.R.id.button1);
+            mPrev.setImageDrawable(sd(prevPath(iconSize), iconSize, pathPaint));
+            addView(mPrev, lp);
+            mPrev.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onNav(v, -1);
+                }
+            });
+
+            lp = new LayoutParams(iconSize, iconSize);
+            lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+            final View v2 = new View(mContext);
+            v2.setBackgroundColor(BACKGROUND);
+            addView(v2, lp);
+            mNext = new ImageView(mContext);
+            mNext.setId(android.R.id.button2);
+            mNext.setImageDrawable(sd(nextPath(iconSize), iconSize, pathPaint));
+            addView(mNext, lp);
+            mNext.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onNav(v, 1);
+                }
+            });
+
+            updateState();
+        }
+
+        private void onNav(View v, int d) {
+            bounce(v, null);
+            if (mAdapter == null) {
+                return;
+            }
+            if (mAdapter.getExitConditionCount() == 1) {
+                horBounce(d);
+                return;
+            }
+            final int w = getWidth();
+            final float s = Math.signum(d);
+            final TextView current = mText;
+            final TextView other = mText == mText1 ? mText2 : mText1;
+            final ExitCondition ec = mAdapter.getExitCondition(d);
+            setText(other, ec);
+            other.setTranslationX(-s * w);
+            other.animate().translationX(0).alpha(1).setDuration(DURATION).start();
+            current.animate().translationX(s * w).alpha(0).setDuration(DURATION).start();
+            mText = other;
+            mAdapter.select(ec);
+        }
+
+        private void horBounce(int d) {
+            final int w = getWidth();
+            mText.animate()
+                    .setDuration(BOUNCE_DURATION)
+                    .translationX(Math.signum(d) * w / 20)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mText.animate().translationX(0).setListener(null).start();
+                        }
+                    }).start();
+        }
+
+        private void setText(final TextView textView, final ExitCondition ec) {
+            SpannableStringBuilder ss = new SpannableStringBuilder(ec.line1 + "\n" + ec.line2);
+            ss.setSpan(new RelativeSizeSpan(1.5f), (ec.line1 + "\n").length(), ss.length(),
+                    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+            if (ec.action != null) {
+                ss.setSpan(new CustomLinkSpan() {
+                    @Override
+                    public void onClick() {
+                        // TODO wire up links
+                        Toast.makeText(mContext, ec.action, Toast.LENGTH_SHORT).show();
+                    }
+                }, (ec.line1 + "\n").length(), ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+                textView.setMovementMethod(LinkMovementMethod.getInstance());
+            } else {
+                textView.setMovementMethod(null);
+            }
+            textView.setText(ss);
+        }
+
+        private void updateState() {
+            if (mAdapter == null) {
+                return;
+            }
+            setText(mText, mAdapter.getExitCondition(0));
+        }
+
+        private Path prevPath(int size) {
+            final int hp = size / 3;
+            final int vp = size / 4;
+            final Path p = new Path();
+            p.moveTo(size - hp, vp);
+            p.lineTo(hp, size / 2);
+            p.lineTo(size - hp, size - vp);
+            return p;
+        }
+
+        private Path nextPath(int size) {
+            final int hp = size / 3;
+            final int vp = size / 4;
+            Path p = new Path();
+            p.moveTo(hp, vp);
+            p.lineTo(size - hp, size / 2);
+            p.lineTo(hp, size - vp);
+            return p;
+        }
+    }
+
+    private abstract static class CustomLinkSpan extends URLSpan {
+        abstract public void onClick();
+
+        public CustomLinkSpan() {
+            super("#");
+        }
+
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            super.updateDrawState(ds);
+            ds.setUnderlineText(false);
+            ds.bgColor = BACKGROUND;
+        }
+
+        @Override
+        public void onClick(View widget) {
+            onClick();
+        }
+    }
+
+    public interface Adapter {
+        public static final int MODE_OFF = 0;
+        public static final int MODE_LIMITED = 1;
+        public static final int MODE_FULL = 2;
+
+        boolean isApplicable();
+        void configure();
+        int getMode();
+        void setMode(int mode);
+        void select(ExitCondition ec);
+        void cancel();
+        void setCallbacks(Callbacks callbacks);
+        ExitCondition getExitCondition(int d);
+        int getExitConditionCount();
+
+        public static class ExitCondition {
+            public String summary;
+            public String line1;
+            public String line2;
+            public String action;
+        }
+
+        public interface Callbacks {
+            void onChanged();
+        }
+    }
+
+    private final class ModeSpinner extends Spinner {
+        public ModeSpinner(final Context context) {
+            super(context);
+            setBackgroundResource(R.drawable.spinner_default_holo_dark_am_no_underline);
+            final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(mContext, 0) {
+                @Override
+                public View getView(int position, View convertView,  ViewGroup parent) {
+                    if (DEBUG) log("getView %s parent=%s", position, parent);
+                    return getDropDownView(position, convertView, parent);
+                }
+
+                @Override
+                public View getDropDownView(int position, View convertView, ViewGroup parent) {
+                    if (DEBUG) log("getDropDownView %s cv=%s parent=%s",
+                            position, convertView, parent);
+                    final TextView tv = convertView != null ? (TextView) convertView
+                            : new TextView(context);
+                    final int mode = getItem(position);
+                    tv.setText(modeToString(mode));
+                    if (convertView == null) {
+                        if (DEBUG) log(" setting up view");
+                        tv.setTextColor(GRAY);
+                        tv.setTypeface(CONDENSED);
+                        tv.setAllCaps(true);
+                        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
+                        final int p = (int) tv.getTextSize() / 2;
+                        if (parent instanceof ListView) {
+                            tv.setPadding(p, p, p, p);
+                        } else {
+                            tv.setGravity(Gravity.CENTER_HORIZONTAL);
+                            tv.setPadding(p, 0, p, 0);
+                        }
+                    }
+                    tv.setOnTouchListener(new OnTouchListener(){
+                        @Override
+                        public boolean onTouch(View v, MotionEvent event) {
+                            if (DEBUG) log("onTouch %s %s", tv.getText(),
+                                    MotionEvent.actionToString(event.getAction()));
+                            if (mAdapter != null) {
+                                mAdapter.setMode(mode);
+                            }
+                            return false;
+                        }
+
+                    });
+                    return tv;
+                }
+            };
+            adapter.add(Adapter.MODE_LIMITED);
+            adapter.add(Adapter.MODE_FULL);
+            setAdapter(adapter);
+        }
+
+        public void updateState() {
+            int mode = mAdapter != null ? mAdapter.getMode() : Adapter.MODE_LIMITED;
+            if (mode == Adapter.MODE_OFF) {
+                mode = Adapter.MODE_LIMITED;
+            }
+            if (DEBUG) log("setSelectedMode " + mode);
+            for (int i = 0; i < getAdapter().getCount(); i++) {
+                if (getAdapter().getItem(i).equals(mode)) {
+                    if (DEBUG) log("  setting selection = " + i);
+                    setSelection(i, true);
+                    return;
+                }
+            }
+        }
+
+        private String modeToString(int mode) {
+            if (mode == Adapter.MODE_LIMITED) return "Limited interruptions";
+            if (mode == Adapter.MODE_FULL) return "Zero interruptions";
+            throw new UnsupportedOperationException("Unsupported mode: " + mode);
+        }
+    }
+
+    private final class AlarmWarning extends LinearLayout {
+        public AlarmWarning(Context context) {
+            super(context);
+            setOrientation(HORIZONTAL);
+
+            final TextView tv = new TextView(mContext);
+            tv.setTextColor(GRAY);
+            tv.setGravity(Gravity.TOP);
+            tv.setTypeface(CONDENSED);
+            tv.setText(FULL_TEXT);
+            addView(tv);
+
+            final ImageView icon = new ImageView(mContext);
+            icon.setAlpha(.75f);
+            int size = (int)tv.getTextSize();
+            icon.setImageResource(android.R.drawable.ic_dialog_alert);
+            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(size, size);
+            final int p = size / 4;
+            lp.bottomMargin = lp.topMargin = lp.rightMargin = lp.leftMargin = p;
+            addView(icon, 0, lp);
+            setPadding(p, 0, p, p);
+        }
+
+        public void updateState(boolean animate) {
+            final boolean visible = mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
+            final float alpha = visible ? 1 : 0;
+            if (alpha == getAlpha()) {
+                return;
+            }
+            if (animate) {
+                final boolean in = alpha == 1;
+                animate().alpha(alpha).setUpdateListener(new AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        if (mPeekable || mClosing) {
+                            return;
+                        }
+                        float f = animation.getAnimatedFraction();
+                        if (!in) {
+                            f = 1 - f;
+                        }
+                        ZenModeView.this.mBottom = mUntilPager.getBottom()
+                                + (int)(mAlarmWarning.getMeasuredHeight() * f);
+                        if (DEBUG) log("mBottom (AW) = " + mBottom);
+                        requestLayout();
+                    }
+                }).start();
+            } else {
+                setAlpha(alpha);
+                requestLayout();
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
new file mode 100644
index 0000000..39c4faa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
+    private static final String TAG = "ZenModeViewAdapter";
+
+    private final Context mContext;
+    private final ContentResolver mResolver;
+    private final Handler mHandler = new Handler();
+    private final SettingsObserver mObserver;
+    private final List<ExitCondition> mExits = Arrays.asList(
+            newExit("Until you delete this", "Until", "You delete this"));
+
+    private Callbacks mCallbacks;
+    private int mExitIndex;
+    private boolean mDeviceProvisioned;
+    private int mMode;
+
+    public ZenModeViewAdapter(Context context) {
+        mContext = context;
+        mResolver = mContext.getContentResolver();
+        mObserver = new SettingsObserver(mHandler);
+        mObserver.init();
+    }
+
+    @Override
+    public boolean isApplicable() {
+        return mDeviceProvisioned;
+    }
+
+    @Override
+    public int getMode() {
+        return mMode;
+    }
+
+    @Override
+    public void setMode(int mode) {
+        final int v = mode == MODE_LIMITED ? Settings.Global.ZEN_MODE_LIMITED
+                    : mode == MODE_FULL ? Settings.Global.ZEN_MODE_FULL
+                    : Settings.Global.ZEN_MODE_OFF;
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                Settings.Global.putInt(mContext.getContentResolver(),
+                        Settings.Global.ZEN_MODE, v);
+            }
+        });
+    }
+
+    @Override
+    public void cancel() {
+        if (mExitIndex != 0) {
+            mExitIndex = 0;
+            mHandler.post(mChange);
+        }
+        setMode(MODE_OFF);
+    }
+
+    @Override
+    public void setCallbacks(final Callbacks callbacks) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mCallbacks = callbacks;
+            }
+        });
+    }
+
+    @Override
+    public ExitCondition getExitCondition(int d) {
+        final int n = mExits.size();
+        final int i = (n + (mExitIndex + (int)Math.signum(d))) % n;
+        return mExits.get(i);
+    }
+
+    @Override
+    public int getExitConditionCount() {
+        return mExits.size();
+    }
+
+    @Override
+    public void select(ExitCondition ec) {
+        final int i = mExits.indexOf(ec);
+        if (i == -1 || i == mExitIndex) {
+            return;
+        }
+        mExitIndex = i;
+        mHandler.post(mChange);
+    }
+
+    private static ExitCondition newExit(String summary, String line1, String line2) {
+        final ExitCondition rt = new ExitCondition();
+        rt.summary = summary;
+        rt.line1 = line1;
+        rt.line2 = line2;
+        return rt;
+    }
+
+    private final Runnable mChange = new Runnable() {
+        public void run() {
+            if (mCallbacks == null) {
+                return;
+            }
+            try {
+                mCallbacks.onChanged();
+            } catch (Throwable t) {
+                Log.w(TAG, "Error dispatching onChanged to " + mCallbacks, t);
+            }
+        }
+    };
+
+    private final class SettingsObserver extends ContentObserver {
+        public SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void init() {
+            loadSettings();
+            mResolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
+                    false, this);
+            mResolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            loadSettings();
+            mChange.run();  // already on handler
+        }
+
+        private void loadSettings() {
+            mDeviceProvisioned = Settings.Global.getInt(mResolver,
+                    Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+            mMode = getMode();
+        }
+
+        private int getMode() {
+            final int v = Settings.Global.getInt(mResolver,
+                    Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+            if (v == Settings.Global.ZEN_MODE_LIMITED) return MODE_LIMITED;
+            if (v == Settings.Global.ZEN_MODE_FULL) return MODE_FULL;
+            return MODE_OFF;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 491c35e..79932a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -28,6 +28,7 @@
 import android.widget.FrameLayout;
 
 import com.android.systemui.ExpandHelper;
+import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -42,13 +43,13 @@
 
     private final int mTouchSensitivityDelay;
     private SwipeHelper mSwipeHelper;
+    private EdgeSwipeHelper mEdgeSwipeHelper;
 
     private BaseStatusBar mBar;
     private ExpandHelper mExpandHelper;
-    private long mStartTouchTime;
 
+    private long mStartTouchTime;
     private ViewGroup mContentHolder;
-    private ViewGroup mContentSlider;
 
     private NotificationData.Entry mHeadsUp;
 
@@ -72,19 +73,24 @@
 
     public boolean setNotification(NotificationData.Entry headsUp) {
         mHeadsUp = headsUp;
-        mHeadsUp.row.setExpanded(false);
-        mHeadsUp.row.setShowingPublic(false);
-        if (mContentHolder == null) {
-            // too soon!
-            return false;
+        if (mContentHolder != null) {
+            mContentHolder.removeAllViews();
         }
-        mContentHolder.setX(0);
-        mContentHolder.setVisibility(View.VISIBLE);
-        mContentHolder.setAlpha(1f);
-        mContentHolder.removeAllViews();
-        mContentHolder.addView(mHeadsUp.row);
-        mSwipeHelper.snapChild(mContentSlider, 1f);
-        mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+
+        if (mHeadsUp != null) {
+            mHeadsUp.row.setExpanded(true);
+            mHeadsUp.row.setShowingPublic(false);
+            if (mContentHolder == null) {
+                // too soon!
+                return false;
+            }
+            mContentHolder.setX(0);
+            mContentHolder.setVisibility(View.VISIBLE);
+            mContentHolder.setAlpha(1f);
+            mContentHolder.addView(mHeadsUp.row);
+            mSwipeHelper.snapChild(mContentHolder, 1f);
+            mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+        }
         return true;
     }
 
@@ -94,10 +100,11 @@
 
     public void setMargin(int notificationPanelMarginPx) {
         if (SPEW) Log.v(TAG, "setMargin() " + notificationPanelMarginPx);
-        if (mContentSlider != null) {
-            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentSlider.getLayoutParams();
+        if (mContentHolder != null &&
+                mContentHolder.getLayoutParams() instanceof FrameLayout.LayoutParams) {
+            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentHolder.getLayoutParams();
             lp.setMarginStart(notificationPanelMarginPx);
-            mContentSlider.setLayoutParams(lp);
+            mContentHolder.setLayoutParams(lp);
         }
     }
 
@@ -122,15 +129,17 @@
     @Override
     public void onAttachedToWindow() {
         float densityScale = getResources().getDisplayMetrics().density;
-        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+        final ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
+        float pagingTouchSlop = viewConfiguration.getScaledPagingTouchSlop();
+        float touchSlop = viewConfiguration.getScaledTouchSlop();
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+        mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop);
 
         int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
         int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
         mExpandHelper = new ExpandHelper(getContext(), this, minHeight, maxHeight);
 
         mContentHolder = (ViewGroup) findViewById(R.id.content_holder);
-        mContentSlider = (ViewGroup) findViewById(R.id.content_slider);
 
         if (mHeadsUp != null) {
             // whoops, we're on already!
@@ -144,7 +153,8 @@
         if (System.currentTimeMillis() < mStartTouchTime) {
             return true;
         }
-        return mSwipeHelper.onInterceptTouchEvent(ev)
+        return mEdgeSwipeHelper.onInterceptTouchEvent(ev)
+                || mSwipeHelper.onInterceptTouchEvent(ev)
                 || mExpandHelper.onInterceptTouchEvent(ev)
                 || super.onInterceptTouchEvent(ev);
     }
@@ -157,7 +167,8 @@
             return false;
         }
         mBar.resetHeadsUpDecayTimer();
-        return mSwipeHelper.onTouchEvent(ev)
+        return mEdgeSwipeHelper.onTouchEvent(ev)
+                || mSwipeHelper.onTouchEvent(ev)
                 || mExpandHelper.onTouchEvent(ev)
                 || super.onTouchEvent(ev);
     }
@@ -226,11 +237,65 @@
 
     @Override
     public View getChildAtPosition(MotionEvent ev) {
-        return mContentSlider;
+        return mContentHolder;
     }
 
     @Override
     public View getChildContentView(View v) {
-        return mContentSlider;
+        return mContentHolder;
+    }
+
+    private class EdgeSwipeHelper implements Gefingerpoken {
+        private static final boolean DEBUG_EDGE_SWIPE = false;
+        private final float mTouchSlop;
+        private boolean mConsuming;
+        private float mFirstY;
+        private float mFirstX;
+
+        public EdgeSwipeHelper(float touchSlop) {
+            mTouchSlop = touchSlop;
+        }
+
+        @Override
+        public boolean onInterceptTouchEvent(MotionEvent ev) {
+            switch (ev.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                    if (DEBUG_EDGE_SWIPE) Log.d(TAG, "action down " + ev.getY());
+                    mFirstX = ev.getX();
+                    mFirstY = ev.getY();
+                    mConsuming = false;
+                    break;
+
+                case MotionEvent.ACTION_MOVE:
+                    if (DEBUG_EDGE_SWIPE) Log.d(TAG, "action move " + ev.getY());
+                    final float dY = ev.getY() - mFirstY;
+                    final float daX = Math.abs(ev.getX() - mFirstX);
+                    final float daY = Math.abs(dY);
+                    if (!mConsuming && (4f * daX) < daY && daY > mTouchSlop) {
+                        if (dY > 0) {
+                            if (DEBUG_EDGE_SWIPE) Log.d(TAG, "found an open");
+                            mBar.animateExpandNotificationsPanel();
+                        }
+                        if (dY < 0) {
+                            if (DEBUG_EDGE_SWIPE) Log.d(TAG, "found a close");
+                            mBar.onHeadsUpDismissed();
+                        }
+                        mConsuming = true;
+                    }
+                    break;
+
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    if (DEBUG_EDGE_SWIPE) Log.d(TAG, "action done" );
+                    mConsuming = false;
+                    break;
+            }
+            return mConsuming;
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev) {
+            return mConsuming;
+        }
     }
 }
\ No newline at end of file
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index f82ca22..0120a03 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -363,36 +363,38 @@
     }
 
     private void addUsersToMenu(ArrayList<Action> items) {
-        List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
-                .getUsers();
-        if (users.size() > 1) {
+        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (um.isUserSwitcherEnabled()) {
+            List<UserInfo> users = um.getUsers();
             UserInfo currentUser = getCurrentUser();
             for (final UserInfo user : users) {
-                boolean isCurrentUser = currentUser == null
-                        ? user.id == 0 : (currentUser.id == user.id);
-                Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
-                        : null;
-                SinglePressAction switchToUser = new SinglePressAction(
-                        com.android.internal.R.drawable.ic_menu_cc, icon,
-                        (user.name != null ? user.name : "Primary")
-                        + (isCurrentUser ? " \u2714" : "")) {
-                    public void onPress() {
-                        try {
-                            ActivityManagerNative.getDefault().switchUser(user.id);
-                        } catch (RemoteException re) {
-                            Log.e(TAG, "Couldn't switch user " + re);
+                if (user.supportsSwitchTo()) {
+                    boolean isCurrentUser = currentUser == null
+                            ? user.id == 0 : (currentUser.id == user.id);
+                    Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
+                            : null;
+                    SinglePressAction switchToUser = new SinglePressAction(
+                            com.android.internal.R.drawable.ic_menu_cc, icon,
+                            (user.name != null ? user.name : "Primary")
+                            + (isCurrentUser ? " \u2714" : "")) {
+                        public void onPress() {
+                            try {
+                                ActivityManagerNative.getDefault().switchUser(user.id);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "Couldn't switch user " + re);
+                            }
                         }
-                    }
 
-                    public boolean showDuringKeyguard() {
-                        return true;
-                    }
+                        public boolean showDuringKeyguard() {
+                            return true;
+                        }
 
-                    public boolean showBeforeProvisioning() {
-                        return false;
-                    }
-                };
-                items.add(switchToUser);
+                        public boolean showBeforeProvisioning() {
+                            return false;
+                        }
+                    };
+                    items.add(switchToUser);
+                }
             }
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index c73d90a..02a2680 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -29,6 +29,8 @@
 import android.transition.Transition;
 import android.transition.TransitionInflater;
 import android.transition.TransitionManager;
+import android.transition.TransitionSet;
+import android.util.ArrayMap;
 import android.view.ViewConfiguration;
 
 import com.android.internal.R;
@@ -105,6 +107,9 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Android-specific Window.
@@ -120,6 +125,13 @@
     private static final long MAX_TRANSITION_START_WAIT = 500;
     private static final long MAX_TRANSITION_FINISH_WAIT = 1000;
 
+    private static final String KEY_SCREEN_X = "shared_element:screenX";
+    private static final String KEY_SCREEN_Y = "shared_element:screenY";
+    private static final String KEY_TRANSLATION_Z = "shared_element:translationZ";
+    private static final String KEY_WIDTH = "shared_element:width";
+    private static final String KEY_HEIGHT = "shared_element:height";
+    private static final String KEY_NAME = "shared_element:name";
+
     /**
      * Simple callback used by the context menu and its submenus. The options
      * menu submenus do not use this (their behavior is more complex).
@@ -239,7 +251,8 @@
 
     private ActivityOptions mActivityOptions;
     private SceneTransitionListener mSceneTransitionListener;
-    private boolean mFadeEarly = true;
+    private boolean mTriggerEarly = true;
+    private Map<String, String> mSharedElementsMap;
 
     static class WindowManagerHolder {
         static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
@@ -2562,6 +2575,11 @@
             return super.fitSystemWindows(insets);
         }
 
+        @Override
+        public boolean isTransitionGroup() {
+            return false;
+        }
+
         private void updateStatusGuard(Rect insets) {
             boolean showStatusGuard = false;
             // Show the status guard when the non-overlay contextual action bar is showing
@@ -3988,78 +4006,214 @@
     }
 
     @Override
-    public void setEarlyBackgroundTransition(boolean fadeEarly) {
-        mFadeEarly = fadeEarly;
+    public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
+        mTriggerEarly = triggerEarly;
     }
 
     @Override
-    public void startExitTransition(ActivityOptions activityOptions) {
-        Transition transition = mTransitionManager.getNamedTransition(getContentScene(), "null");
-        if (transition == null) {
-            transition = TransitionManager.getDefaultTransition().clone();
+    public void mapTransitionTargets(Map<String, String> sharedElementNames) {
+        mSharedElementsMap = sharedElementNames;
+    }
+
+    @Override
+    public Bundle startExitTransition(ActivityOptions activityOptions) {
+        if (mContentScene == null) {
+            return null;
         }
-        activityOptions.setExitTransition(transition, new ActivityOptions.SharedElementSource() {
+        Transition transition = mTransitionManager.getExitTransition(mContentScene);
+        if (transition == null) {
+            return null;
+        }
+
+        ArrayMap<String, View> sharedElements = findSharedElements(activityOptions);
+
+        // Find exiting Views and shared elements
+        final ArrayList<View> transitioningViews = new ArrayList<View>();
+        mDecor.captureTransitioningViews(transitioningViews);
+        transitioningViews.removeAll(sharedElements.values());
+
+        Transition exitTransition = cloneAndSetTransitionTargets(transition,
+                transitioningViews, true);
+        Transition sharedElementTransition = cloneAndSetTransitionTargets(transition,
+                transitioningViews, false);
+
+        // transitionSet is the total exit transition, including hero animation.
+        TransitionSet transitionSet = new TransitionSet();
+        transitionSet.addTransition(exitTransition);
+        transitionSet.addTransition(sharedElementTransition);
+
+        updateExitActivityOptions(activityOptions, sharedElements,
+                sharedElementTransition, exitTransition);
+
+        // Start exiting the Views that need to exit
+        TransitionManager.beginDelayedTransition(mDecor, transitionSet);
+        setViewVisibility(transitioningViews, View.INVISIBLE);
+
+        return activityOptions.toBundle();
+    }
+
+    private ArrayMap<String, View> findSharedElements(ActivityOptions activityOptions) {
+        ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
+        mDecor.findSharedElements(sharedElements);
+        ArrayList<String> localNames = activityOptions.getLocalElementNames();
+        sharedElements.keySet().retainAll(localNames);
+
+        ArrayList<String> targetNames = activityOptions.getSharedElementNames();
+        for (int i = 0; i < localNames.size(); i++) {
+            String localName = localNames.get(i);
+            View sharedElement = sharedElements.remove(localName);
+            String targetName = targetNames.get(i);
+            sharedElements.put(targetName, sharedElement);
+        }
+        return sharedElements;
+    }
+
+    private void updateExitActivityOptions(ActivityOptions activityOptions,
+            final Map<String, View> sharedElements, Transition sharedElementTransition,
+            Transition exitTransition) {
+
+        // Schedule capturing of the shared element state
+        final Bundle sharedElementArgs = new Bundle();
+        captureTerminalSharedElementState(sharedElements, sharedElementArgs);
+
+        ActivityOptions.SharedElementSource sharedElementSource
+                = new ActivityOptions.SharedElementSource() {
             @Override
-            public int getTextureId() {
-                // TODO: move shared elements to a layer and return the texture id
-                recurseHideExitingSharedElements(mContentParent);
-                return 0;
+            public Bundle getSharedElementExitState() {
+                return sharedElementArgs;
+            }
+
+            @Override
+            public void acceptedSharedElements(ArrayList<String> sharedElementNames) {
+                if (sharedElementNames.size() == sharedElements.size()) {
+                    return; // They were all accepted
+                }
+                Transition transition = mTransitionManager.getExitTransition(mContentScene).clone();
+                TransitionManager.beginDelayedTransition(mDecor, transition);
+                for (String name: sharedElements.keySet()) {
+                    if (!sharedElementNames.contains(name)) {
+                        sharedElements.get(name).setVisibility(View.INVISIBLE);
+                    }
+                }
+                sharedElements.keySet().retainAll(sharedElementNames);
+            }
+
+            @Override
+            public void hideSharedElements() {
+                if (sharedElements != null) {
+                    setViewVisibility(sharedElements.values(), View.INVISIBLE);
+                }
+            }
+        };
+
+        activityOptions.updateSceneTransitionAnimation(
+                exitTransition, sharedElementTransition, sharedElementSource);
+    }
+
+    private void captureTerminalSharedElementState(final Map<String, View> sharedElements,
+            final Bundle sharedElementArgs) {
+        mDecor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                mDecor.getViewTreeObserver().removeOnPreDrawListener(this);
+                int[] tempLoc = new int[2];
+                for (String name : sharedElements.keySet()) {
+                    View sharedElement = sharedElements.get(name);
+                    captureSharedElementState(sharedElement, name, sharedElementArgs, tempLoc);
+                }
+                return true;
             }
         });
-        ViewGroup sceneRoot = getContentScene().getSceneRoot();
-        TransitionManager.beginDelayedTransition(sceneRoot, transition);
-        recurseExitNonSharedElements(mContentParent);
     }
 
-    private static void recurseExitNonSharedElements(ViewGroup viewGroup) {
-        int numChildren = viewGroup.getChildCount();
-        for (int i = 0; i < numChildren; i++) {
-            View child = viewGroup.getChildAt(i);
-            if (child.getSharedElementName() != null || (child.getVisibility() != View.VISIBLE)) {
-                continue;
-            }
-            if (child instanceof ViewGroup && !((ViewGroup)child).isTransitionGroup()) {
-                recurseExitNonSharedElements((ViewGroup) child);
+    private static Transition cloneAndSetTransitionTargets(Transition transition,
+            List<View> views, boolean add) {
+        transition = transition.clone();
+        if (!transition.getTargetIds().isEmpty() || !transition.getTargets().isEmpty()) {
+            TransitionSet set = new TransitionSet();
+            set.addTransition(transition);
+            transition = set;
+        }
+        for (View view: views) {
+            if (add) {
+                transition.addTarget(view);
             } else {
-                child.setVisibility(View.INVISIBLE);
+                transition.excludeTarget(view, true);
             }
         }
+        return transition;
+    }
+
+    private static void setViewVisibility(Collection<View> views, int visibility) {
+        for (View view : views) {
+            view.setVisibility(visibility);
+        }
     }
 
-    private static void recurseHideViews(ViewGroup viewGroup, ArrayList<View> nonSharedElements,
-            ArrayList<View> sharedElements) {
-        int numChildren = viewGroup.getChildCount();
-        for (int i = 0; i < numChildren; i++) {
-            View child = viewGroup.getChildAt(i);
-            if (child.getVisibility() != View.VISIBLE) {
-                continue;
-            }
-            if (child.getSharedElementName() != null) {
-                sharedElements.add(child);
-                child.setVisibility(View.INVISIBLE);
-            } else if (child instanceof ViewGroup && !((ViewGroup)child).isTransitionGroup()) {
-                recurseHideViews((ViewGroup) child, nonSharedElements, sharedElements);
-            } else {
-                nonSharedElements.add(child);
-                child.setVisibility(View.INVISIBLE);
-            }
+    /**
+     * Sets the captured values from a previous
+     * {@link #captureSharedElementState(android.view.View, String, android.os.Bundle, int[])}
+     * @param view The View to apply placement changes to.
+     * @param name The shared element name given from the source Activity.
+     * @param transitionArgs A <code>Bundle</code> containing all placementinformation for named
+     *                       shared elements in the scene.
+     * @param tempLoc A temporary int[2] for capturing the current location of views.
+     */
+    private static void setSharedElementState(View view, String name, Bundle transitionArgs,
+            int[] tempLoc) {
+        Bundle sharedElementBundle = transitionArgs.getBundle(name);
+        if (sharedElementBundle == null) {
+            return;
         }
+
+        int x = sharedElementBundle.getInt(KEY_SCREEN_X);
+        view.getLocationOnScreen(tempLoc);
+        int offsetX = x - tempLoc[0];
+        view.offsetLeftAndRight(offsetX);
+
+        int width = sharedElementBundle.getInt(KEY_WIDTH);
+        view.setRight(view.getLeft() + width);
+
+        int y = sharedElementBundle.getInt(KEY_SCREEN_Y);
+        int offsetY = y - tempLoc[1];
+        view.offsetTopAndBottom(offsetY);
+
+        int height = sharedElementBundle.getInt(KEY_HEIGHT);
+        view.setBottom(view.getTop() + height);
+
+        float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z);
+        view.setTranslationZ(z);
     }
 
-    private static void recurseHideExitingSharedElements(ViewGroup viewGroup) {
-        int numChildren = viewGroup.getChildCount();
-        for (int i = 0; i < numChildren; i++) {
-            View child = viewGroup.getChildAt(i);
-            if (child.getVisibility() != View.VISIBLE) {
-                continue;
-            }
-            if (child.getSharedElementName() != null) {
-                child.setVisibility(View.INVISIBLE);
-            } else if (child instanceof ViewGroup) {
-                ViewGroup childViewGroup = (ViewGroup) child;
-                recurseHideExitingSharedElements(childViewGroup);
-            }
-        }
+    /**
+     * Captures placement information for Views with a shared element name for
+     * Activity Transitions.
+     * @param view The View to capture the placement information for.
+     * @param name The shared element name in the target Activity to apply the placement
+     *             information for.
+     * @param transitionArgs Bundle to store shared element placement information.
+     * @param tempLoc A temporary int[2] for capturing the current location of views.
+     * @see #setSharedElementState(android.view.View, String, android.os.Bundle, int[])
+     */
+    private static void captureSharedElementState(View view, String name, Bundle transitionArgs,
+            int[] tempLoc) {
+        Bundle sharedElementBundle = new Bundle();
+        view.getLocationOnScreen(tempLoc);
+        float scaleX = view.getScaleX();
+        sharedElementBundle.putInt(KEY_SCREEN_X, tempLoc[0]);
+        int width = Math.round(view.getWidth() * scaleX);
+        sharedElementBundle.putInt(KEY_WIDTH, width);
+
+        float scaleY = view.getScaleY();
+        sharedElementBundle.putInt(KEY_SCREEN_Y, tempLoc[1]);
+        int height= Math.round(view.getHeight() * scaleY);
+        sharedElementBundle.putInt(KEY_HEIGHT, height);
+
+        sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ());
+
+        sharedElementBundle.putString(KEY_NAME, view.getSharedElementName());
+
+        transitionArgs.putBundle(name, sharedElementBundle);
     }
 
     /**
@@ -4080,46 +4234,57 @@
         private boolean mAllDone;
         private Handler mHandler = new Handler();
         private boolean mEnterTransitionStarted;
-        private ArrayList<View> mSharedElements = new ArrayList<View>();
+        private ArrayMap<String, View> mSharedElementTargets = new ArrayMap<String, View>();
+        private ArrayList<View> mEnteringViews = new ArrayList<View>();
 
         public EnterScene() {
             mSceneTransitionListener.nullPendingTransition();
             Drawable background = getDecorView().getBackground();
             if (background != null) {
-                setBackgroundDrawable(null);
                 background.setAlpha(0);
-                setBackgroundDrawable(background);
+                mDecor.drawableChanged();
             }
             mSceneTransitionListener.convertToTranslucent();
         }
 
         @Override
         public boolean onPreDraw() {
-            ViewTreeObserver observer = mContentParent.getViewTreeObserver();
+            ViewTreeObserver observer = mDecor.getViewTreeObserver();
             observer.removeOnPreDrawListener(this);
             if (!mEnterTransitionStarted && mSceneTransitionListener != null) {
                 mEnterTransitionStarted = true;
-                ArrayList<View> enteringViews = new ArrayList<View>();
-                recurseHideViews(mContentParent, enteringViews, mSharedElements);
-                Transition transition = getTransitionManager().getNamedTransition("null",
-                        mContentScene);
-                if (transition == null) {
-                    transition = TransitionManager.getDefaultTransition().clone();
+                mDecor.captureTransitioningViews(mEnteringViews);
+                ArrayList<String> sharedElementNames = mActivityOptions.getSharedElementNames();
+                if (sharedElementNames != null) {
+                    mDecor.findSharedElements(mSharedElementTargets);
+                    if (mSharedElementsMap != null) {
+                        for (Map.Entry<String, String> entry : mSharedElementsMap.entrySet()) {
+                            View sharedElement = mSharedElementTargets.remove(entry.getValue());
+                            if (sharedElement != null) {
+                                mSharedElementTargets.put(entry.getKey(), sharedElement);
+                            }
+                        }
+                    }
+                    mSharedElementTargets.keySet().retainAll(sharedElementNames);
+                    mEnteringViews.removeAll(mSharedElementTargets.values());
                 }
-                TransitionManager.beginDelayedTransition(mContentParent, transition);
-                for (View hidden : enteringViews) {
-                    hidden.setVisibility(View.VISIBLE);
+
+                setViewVisibility(mEnteringViews, View.INVISIBLE);
+                setViewVisibility(mSharedElementTargets.values(), View.INVISIBLE);
+                if (mTriggerEarly) {
+                    beginEnterScene();
                 }
                 observer.addOnPreDrawListener(this);
             } else {
                 mHandler.postDelayed(this, MAX_TRANSITION_START_WAIT);
-                mActivityOptions.dispatchSceneTransitionStarted(this);
+                mActivityOptions.dispatchSceneTransitionStarted(this,
+                        new ArrayList<String>(mSharedElementTargets.keySet()));
             }
             return true;
         }
 
         public void start() {
-            ViewTreeObserver observer = mContentParent.getViewTreeObserver();
+            ViewTreeObserver observer = mDecor.getViewTreeObserver();
             observer.addOnPreDrawListener(this);
         }
 
@@ -4129,25 +4294,43 @@
         }
 
         @Override
-        public void sharedElementTransitionComplete() {
+        public void sharedElementTransitionComplete(Bundle transitionArgs) {
             if (!mSharedElementReadyReceived) {
                 mSharedElementReadyReceived = true;
                 mHandler.removeCallbacks(this);
                 mHandler.postDelayed(this, MAX_TRANSITION_FINISH_WAIT);
-                for (View sharedElement: mSharedElements) {
-                    sharedElement.setVisibility(View.VISIBLE);
-                }
-                mSharedElements.clear();
-                mContentParent.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        mContentParent.getViewTreeObserver().removeOnPreDrawListener(this);
-                        mSceneTransitionListener.enterSharedElement(
-                                mActivityOptions.getSceneTransitionArgs());
-                        return false;
+                if (!mSharedElementTargets.isEmpty()) {
+                    Transition transition = getTransitionManager().getEnterTransition(
+                            mContentScene);
+                    if (transition == null) {
+                        transition = TransitionManager.getDefaultTransition();
                     }
-                });
-                if (mFadeEarly) {
+                    transition = transition.clone();
+                    if (transitionArgs == null) {
+                        TransitionManager.beginDelayedTransition(mDecor, transition);
+                        setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
+                    } else {
+                        int[] tempLoc = new int[2];
+                        for (Map.Entry<String, View> entry: mSharedElementTargets.entrySet()) {
+                            setSharedElementState(entry.getValue(), entry.getKey(), transitionArgs,
+                                    tempLoc);
+                        }
+                        setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
+                        mSceneTransitionListener.sharedElementStart(transition);
+                        mDecor.getViewTreeObserver().addOnPreDrawListener(
+                                new ViewTreeObserver.OnPreDrawListener() {
+                                    @Override
+                                    public boolean onPreDraw() {
+                                        mDecor.getViewTreeObserver().removeOnPreDrawListener(this);
+                                        mSceneTransitionListener.sharedElementEnd();
+                                        mActivityOptions.dispatchSharedElementsReady();
+                                        return true;
+                                    }
+                                });
+                        TransitionManager.beginDelayedTransition(mDecor, transition);
+                    }
+                }
+                if (mTriggerEarly) {
                     fadeInBackground();
                 }
             }
@@ -4170,9 +4353,10 @@
                 return;
             }
             mAllDone = true;
-            sharedElementTransitionComplete();
+            sharedElementTransitionComplete(null);
             mHandler.removeCallbacks(this);
-            if (!mFadeEarly) {
+            if (!mTriggerEarly) {
+                beginEnterScene();
                 fadeInBackground();
             }
         }
@@ -4193,5 +4377,14 @@
         @Override
         public void onAnimationRepeat(Animator animation) {
         }
+
+        private void beginEnterScene() {
+            Transition transition = getTransitionManager().getEnterTransition(mContentScene);
+            if (transition == null) {
+                transition = TransitionManager.getDefaultTransition().clone();
+            }
+            TransitionManager.beginDelayedTransition(mDecor, transition);
+            setViewVisibility(mEnteringViews, View.VISIBLE);
+        }
     }
 }
diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java
index b386dd7..1372ab7 100644
--- a/rs/java/android/renderscript/BaseObj.java
+++ b/rs/java/android/renderscript/BaseObj.java
@@ -181,6 +181,10 @@
         if (this == obj)
             return true;
 
+        if (obj == null) {
+            return false;
+        }
+
         if (getClass() != obj.getClass()) {
             return false;
         }
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 93e839e..55b671d 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -800,8 +800,6 @@
     void updateFromNative() {
         super.updateFromNative();
 
-        // FIXME: updateFromNative is broken in JNI for 64-bit
-
         // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
         int[] dataBuffer = new int[5];
         mRS.nElementGetNativeData(getID(mRS), dataBuffer);
@@ -828,7 +826,7 @@
             mArraySizes = new int[numSubElements];
             mOffsetInBytes = new int[numSubElements];
 
-            int[] subElementIds = new int[numSubElements];
+            long[] subElementIds = new long[numSubElements];
             mRS.nElementGetSubElements(getID(mRS), subElementIds, mElementNames, mArraySizes);
             for(int i = 0; i < numSubElements; i ++) {
                 mElements[i] = new Element(subElementIds[i], mRS);
@@ -1087,10 +1085,9 @@
             java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
             java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
 
-            // FIXME: broken for 64-bit
-            int[] ids = new int[ein.length];
+            long[] ids = new long[ein.length];
             for (int ct = 0; ct < ein.length; ct++ ) {
-                ids[ct] = (int)ein[ct].getID(mRS);
+                ids[ct] = ein[ct].getID(mRS);
             }
             long id = mRS.nElementCreate2(ids, sin, asin);
             return new Element(id, mRS, ein, sin, asin);
diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java
index a4ecc38..1a5dc9e 100644
--- a/rs/java/android/renderscript/Mesh.java
+++ b/rs/java/android/renderscript/Mesh.java
@@ -152,8 +152,8 @@
         int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS));
         int idxCount = mRS.nMeshGetIndexCount(getID(mRS));
 
-        int[] vtxIDs = new int[vtxCount];
-        int[] idxIDs = new int[idxCount];
+        long[] vtxIDs = new long[vtxCount];
+        long[] idxIDs = new long[idxCount];
         int[] primitives = new int[idxCount];
 
         mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount);
@@ -348,8 +348,8 @@
         **/
         public Mesh create() {
             mRS.validate();
-            int[] vtx = new int[mVertexTypeCount];
-            int[] idx = new int[mIndexTypes.size()];
+            long[] vtx = new long[mVertexTypeCount];
+            long[] idx = new long[mIndexTypes.size()];
             int[] prim = new int[mIndexTypes.size()];
 
             Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
@@ -365,7 +365,7 @@
                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                 }
                 vertexBuffers[ct] = alloc;
-                vtx[ct] = (int)alloc.getID(mRS);
+                vtx[ct] = alloc.getID(mRS);
             }
 
             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
@@ -380,7 +380,7 @@
                 indexBuffers[ct] = alloc;
                 primitives[ct] = entry.prim;
 
-                idx[ct] = (int)allocID;
+                idx[ct] = allocID;
                 prim[ct] = entry.prim.mID;
             }
 
@@ -504,8 +504,8 @@
         public Mesh create() {
             mRS.validate();
 
-            int[] vtx = new int[mVertexTypeCount];
-            int[] idx = new int[mIndexTypes.size()];
+            long[] vtx = new long[mVertexTypeCount];
+            long[] idx = new long[mIndexTypes.size()];
             int[] prim = new int[mIndexTypes.size()];
 
             Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
@@ -515,7 +515,7 @@
             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
                 Entry entry = mVertexTypes[ct];
                 vertexBuffers[ct] = entry.a;
-                vtx[ct] = (int)entry.a.getID(mRS);
+                vtx[ct] = entry.a.getID(mRS);
             }
 
             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
@@ -524,7 +524,7 @@
                 indexBuffers[ct] = entry.a;
                 primitives[ct] = entry.prim;
 
-                idx[ct] = (int)allocID;
+                idx[ct] = allocID;
                 prim[ct] = entry.prim.mID;
             }
 
diff --git a/rs/java/android/renderscript/ProgramFragment.java b/rs/java/android/renderscript/ProgramFragment.java
index 2704130..5f71bd1 100644
--- a/rs/java/android/renderscript/ProgramFragment.java
+++ b/rs/java/android/renderscript/ProgramFragment.java
@@ -62,25 +62,25 @@
          */
         public ProgramFragment create() {
             mRS.validate();
-            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
+            long[] tmp = new long[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
             String[] texNames = new String[mTextureCount];
             int idx = 0;
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = (int)mInputs[i].getID(mRS);
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = (int)mOutputs[i].getID(mRS);
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = (int)mConstants[i].getID(mRS);
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = (int)mTextureTypes[i].mID;
+                tmp[idx++] = mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
diff --git a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
index e1c35c5..2b647c76 100644
--- a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -49,25 +49,25 @@
          */
         public ProgramFragmentFixedFunction create() {
             mRS.validate();
-            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
+            long[] tmp = new long[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
             String[] texNames = new String[mTextureCount];
             int idx = 0;
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = (int)mInputs[i].getID(mRS);
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = (int)mOutputs[i].getID(mRS);
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = (int)mConstants[i].getID(mRS);
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = (int)mTextureTypes[i].mID;
+                tmp[idx++] = mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
diff --git a/rs/java/android/renderscript/ProgramVertex.java b/rs/java/android/renderscript/ProgramVertex.java
index d194ba9..0d7e2d9 100644
--- a/rs/java/android/renderscript/ProgramVertex.java
+++ b/rs/java/android/renderscript/ProgramVertex.java
@@ -122,25 +122,25 @@
          */
         public ProgramVertex create() {
             mRS.validate();
-            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
+            long[] tmp = new long[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
             String[] texNames = new String[mTextureCount];
             int idx = 0;
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = (int)mInputs[i].getID(mRS);
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = (int)mOutputs[i].getID(mRS);
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = (int)mConstants[i].getID(mRS);
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = (int)mTextureTypes[i].mID;
+                tmp[idx++] = mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
index 2d281b8..5173af2 100644
--- a/rs/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -75,25 +75,25 @@
          */
         public ProgramVertexFixedFunction create() {
             mRS.validate();
-            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
+            long[] tmp = new long[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
             String[] texNames = new String[mTextureCount];
             int idx = 0;
 
             for (int i=0; i < mInputCount; i++) {
                 tmp[idx++] = ProgramParam.INPUT.mID;
-                tmp[idx++] = (int)mInputs[i].getID(mRS);
+                tmp[idx++] = mInputs[i].getID(mRS);
             }
             for (int i=0; i < mOutputCount; i++) {
                 tmp[idx++] = ProgramParam.OUTPUT.mID;
-                tmp[idx++] = (int)mOutputs[i].getID(mRS);
+                tmp[idx++] = mOutputs[i].getID(mRS);
             }
             for (int i=0; i < mConstantCount; i++) {
                 tmp[idx++] = ProgramParam.CONSTANT.mID;
-                tmp[idx++] = (int)mConstants[i].getID(mRS);
+                tmp[idx++] = mConstants[i].getID(mRS);
             }
             for (int i=0; i < mTextureCount; i++) {
                 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
-                tmp[idx++] = (int)mTextureTypes[i].mID;
+                tmp[idx++] = mTextureTypes[i].mID;
                 texNames[i] = mTextureNames[i];
             }
 
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 89dba9f..4dd6045 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -303,8 +303,8 @@
         validate();
         return rsnElementCreate(mContext, type, kind, norm, vecSize);
     }
-    native long rsnElementCreate2(long con, int[]elements, String[] names, int[] arraySizes);
-    synchronized long nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
+    native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
+    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
         validate();
         return rsnElementCreate2(mContext, elements, names, arraySizes);
     }
@@ -314,8 +314,8 @@
         rsnElementGetNativeData(mContext, id, elementData);
     }
     native void rsnElementGetSubElements(long con, long id,
-                                         int[] IDs, String[] names, int[] arraySizes);
-    synchronized void nElementGetSubElements(long id, int[] IDs, String[] names, int[] arraySizes) {
+                                         long[] IDs, String[] names, int[] arraySizes);
+    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
         validate();
         rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
     }
@@ -325,14 +325,14 @@
         validate();
         return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
     }
-    native void rsnTypeGetNativeData(long con, long id, int[] typeData);
-    synchronized void nTypeGetNativeData(long id, int[] typeData) {
+    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
+    synchronized void nTypeGetNativeData(long id, long[] typeData) {
         validate();
         rsnTypeGetNativeData(mContext, id, typeData);
     }
 
-    native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, int pointer);
-    synchronized long nAllocationCreateTyped(long type, int mip, int usage, int pointer) {
+    native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
+    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
         validate();
         return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
     }
@@ -700,8 +700,8 @@
         return rsnScriptFieldIDCreate(mContext, sid, slot);
     }
 
-    native long rsnScriptGroupCreate(long con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
-    synchronized long nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
+    native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
+    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
         validate();
         return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
     }
@@ -764,19 +764,19 @@
         validate();
         rsnProgramBindSampler(mContext, vpf, slot, s);
     }
-    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, int[] params);
-    synchronized long nProgramFragmentCreate(String shader, String[] texNames, int[] params) {
+    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, long[] params);
+    synchronized long nProgramFragmentCreate(String shader, String[] texNames, long[] params) {
         validate();
         return rsnProgramFragmentCreate(mContext, shader, texNames, params);
     }
-    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, int[] params);
-    synchronized long nProgramVertexCreate(String shader, String[] texNames, int[] params) {
+    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, long[] params);
+    synchronized long nProgramVertexCreate(String shader, String[] texNames, long[] params) {
         validate();
         return rsnProgramVertexCreate(mContext, shader, texNames, params);
     }
 
-    native long rsnMeshCreate(long con, int[] vtx, int[] idx, int[] prim);
-    synchronized long nMeshCreate(int[] vtx, int[] idx, int[] prim) {
+    native long rsnMeshCreate(long con, long[] vtx, long[] idx, int[] prim);
+    synchronized long nMeshCreate(long[] vtx, long[] idx, int[] prim) {
         validate();
         return rsnMeshCreate(mContext, vtx, idx, prim);
     }
@@ -790,13 +790,13 @@
         validate();
         return rsnMeshGetIndexCount(mContext, id);
     }
-    native void rsnMeshGetVertices(long con, long id, int[] vtxIds, int vtxIdCount);
-    synchronized void nMeshGetVertices(long id, int[] vtxIds, int vtxIdCount) {
+    native void rsnMeshGetVertices(long con, long id, long[] vtxIds, int vtxIdCount);
+    synchronized void nMeshGetVertices(long id, long[] vtxIds, int vtxIdCount) {
         validate();
         rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
     }
-    native void rsnMeshGetIndices(long con, long id, int[] idxIds, int[] primitives, int vtxIdCount);
-    synchronized void nMeshGetIndices(long id, int[] idxIds, int[] primitives, int vtxIdCount) {
+    native void rsnMeshGetIndices(long con, long id, long[] idxIds, int[] primitives, int vtxIdCount);
+    synchronized void nMeshGetIndices(long id, long[] idxIds, int[] primitives, int vtxIdCount) {
         validate();
         rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
     }
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index f1a7273..51c838f 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -379,7 +379,6 @@
          * @return ScriptGroup The new ScriptGroup
          */
         public ScriptGroup create() {
-            // FIXME: this is broken for 64-bit
 
             if (mNodes.size() == 0) {
                 throw new RSInvalidStateException("Empty script groups are not allowed");
@@ -394,13 +393,13 @@
             ArrayList<IO> inputs = new ArrayList<IO>();
             ArrayList<IO> outputs = new ArrayList<IO>();
 
-            int[] kernels = new int[mKernelCount];
+            long[] kernels = new long[mKernelCount];
             int idx = 0;
             for (int ct=0; ct < mNodes.size(); ct++) {
                 Node n = mNodes.get(ct);
                 for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
                     final Script.KernelID kid = n.mKernels.get(ct2);
-                    kernels[idx++] = (int)kid.getID(mRS);
+                    kernels[idx++] = kid.getID(mRS);
 
                     boolean hasInput = false;
                     boolean hasOutput = false;
@@ -427,21 +426,21 @@
                 throw new RSRuntimeException("Count mismatch, should not happen.");
             }
 
-            int[] src = new int[mLines.size()];
-            int[] dstk = new int[mLines.size()];
-            int[] dstf = new int[mLines.size()];
-            int[] types = new int[mLines.size()];
+            long[] src = new long[mLines.size()];
+            long[] dstk = new long[mLines.size()];
+            long[] dstf = new long[mLines.size()];
+            long[] types = new long[mLines.size()];
 
             for (int ct=0; ct < mLines.size(); ct++) {
                 ConnectLine cl = mLines.get(ct);
-                src[ct] = (int)cl.mFrom.getID(mRS);
+                src[ct] = cl.mFrom.getID(mRS);
                 if (cl.mToK != null) {
-                    dstk[ct] = (int)cl.mToK.getID(mRS);
+                    dstk[ct] = cl.mToK.getID(mRS);
                 }
                 if (cl.mToF != null) {
-                    dstf[ct] = (int)cl.mToF.getID(mRS);
+                    dstf[ct] = cl.mToF.getID(mRS);
                 }
-                types[ct] = (int)cl.mAllocationType.getID(mRS);
+                types[ct] = cl.mAllocationType.getID(mRS);
             }
 
             long id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java
index 83bf4a5..98aeaa9 100644
--- a/rs/java/android/renderscript/Type.java
+++ b/rs/java/android/renderscript/Type.java
@@ -190,20 +190,18 @@
 
     @Override
     void updateFromNative() {
-        // FIXME: rsaTypeGetNativeData needs 32-bit and 64-bit paths
-
-        // We have 6 integer to obtain mDimX; mDimY; mDimZ;
+        // We have 6 integer/long to obtain mDimX; mDimY; mDimZ;
         // mDimLOD; mDimFaces; mElement;
-        int[] dataBuffer = new int[6];
-        mRS.nTypeGetNativeData((int)getID(mRS), dataBuffer);
+        long[] dataBuffer = new long[6];
+        mRS.nTypeGetNativeData(getID(mRS), dataBuffer);
 
-        mDimX = dataBuffer[0];
-        mDimY = dataBuffer[1];
-        mDimZ = dataBuffer[2];
+        mDimX = (int)dataBuffer[0];
+        mDimY = (int)dataBuffer[1];
+        mDimZ = (int)dataBuffer[2];
         mDimMipmaps = dataBuffer[3] == 1 ? true : false;
         mDimFaces = dataBuffer[4] == 1 ? true : false;
 
-        int elementID = dataBuffer[5];
+        long elementID = dataBuffer[5];
         if(elementID != 0) {
             mElement = new Element(elementID, mRS);
             mElement.updateFromNative();
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index cbb5b3b..07933b4 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -23,8 +23,7 @@
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE) \
 	frameworks/rs \
-	$(rs_generated_include_dir) \
-	$(call include-path-for, corecg graphics)
+	$(rs_generated_include_dir)
 
 LOCAL_CFLAGS += -Wno-unused-parameter
 
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 80a5da2..b547706 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -23,10 +23,7 @@
 #include <math.h>
 #include <utils/misc.h>
 
-#include <core/SkBitmap.h>
-#include <core/SkPixelRef.h>
-#include <core/SkStream.h>
-#include <core/SkTemplates.h>
+#include <SkBitmap.h>
 
 #include <androidfw/Asset.h>
 #include <androidfw/AssetManager.h>
@@ -412,13 +409,21 @@
 
 static jlong
 nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
-                jintArray _ids, jobjectArray _names, jintArray _arraySizes)
+                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
 {
     int fieldCount = _env->GetArrayLength(_ids);
     LOG_API("nElementCreate2, con(%p)", (RsContext)con);
 
-    jint *ids = _env->GetIntArrayElements(_ids, NULL);
-    jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
+    jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
+    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
+
+    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
+    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
+
+    for(int i = 0; i < fieldCount; i ++) {
+        ids[i] = (RsElement)jIds[i];
+        arraySizes[i] = (uint32_t)jArraySizes[i];
+    }
 
     AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
 
@@ -426,12 +431,15 @@
     size_t *sizeArray = names.c_str_len();
 
     jlong id = (jlong)rsElementCreate2((RsContext)con,
-                                     (RsElement *)ids, fieldCount,
+                                     (const RsElement *)ids, fieldCount,
                                      nameArray, fieldCount * sizeof(size_t),  sizeArray,
                                      (const uint32_t *)arraySizes, fieldCount);
 
-    _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
-    _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
+    free(ids);
+    free(arraySizes);
+    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
+    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
+
     return (jlong)id;
 }
 
@@ -448,30 +456,33 @@
     rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
 
     for(jint i = 0; i < dataSize; i ++) {
-        _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]);
+        const jint data = (jint)elementData[i];
+        _env->SetIntArrayRegion(_elementData, i, 1, &data);
     }
 }
 
 
 static void
 nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
-                       jintArray _IDs,
+                       jlongArray _IDs,
                        jobjectArray _names,
                        jintArray _arraySizes)
 {
-    int dataSize = _env->GetArrayLength(_IDs);
+    uint32_t dataSize = _env->GetArrayLength(_IDs);
     LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
 
-    uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
-    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
-    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
+    uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
+    const char **names = (const char **)malloc(dataSize * sizeof(const char *));
+    size_t *arraySizes = (size_t *)malloc(dataSize * sizeof(size_t));
 
     rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
 
-    for(jint i = 0; i < dataSize; i++) {
+    for(uint32_t i = 0; i < dataSize; i++) {
+        const jlong id = (jlong)ids[i];
+        const jint arraySize = (jint)arraySizes[i];
         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
-        _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
-        _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]);
+        _env->SetLongArrayRegion(_IDs, i, 1, &id);
+        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
     }
 
     free(ids);
@@ -492,7 +503,7 @@
 }
 
 static void
-nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _typeData)
+nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jlongArray _typeData)
 {
     // We are packing 6 items: mDimX; mDimY; mDimZ;
     // mDimLOD; mDimFaces; mElement; into typeData
@@ -501,21 +512,22 @@
     assert(elementCount == 6);
     LOG_API("nTypeGetNativeData, con(%p)", (RsContext)con);
 
-    uint32_t typeData[6];
+    uintptr_t typeData[6];
     rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
 
     for(jint i = 0; i < elementCount; i ++) {
-        _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]);
+        const jlong data = (jlong)typeData[i];
+        _env->SetLongArrayRegion(_typeData, i, 1, &data);
     }
 }
 
 // -----------------------------------
 
 static jlong
-nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jint pointer)
+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, (uint32_t)pointer);
+    return (jlong) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
 }
 
 static void
@@ -601,7 +613,7 @@
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)rsAllocationCreateTyped((RsContext)con,
                                             (RsType)type, (RsAllocationMipmapControl)mip,
-                                            (uint32_t)usage, (size_t)ptr);
+                                            (uint32_t)usage, (uintptr_t)ptr);
     bitmap.unlockPixels();
     return id;
 }
@@ -1196,34 +1208,63 @@
 }
 
 static jlong
-nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jintArray _kernels, jintArray _src,
-    jintArray _dstk, jintArray _dstf, jintArray _types)
+nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
+    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
 {
     LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
 
-    jint kernelsLen = _env->GetArrayLength(_kernels) * sizeof(int);
-    jint *kernelsPtr = _env->GetIntArrayElements(_kernels, NULL);
-    jint srcLen = _env->GetArrayLength(_src) * sizeof(int);
-    jint *srcPtr = _env->GetIntArrayElements(_src, NULL);
-    jint dstkLen = _env->GetArrayLength(_dstk) * sizeof(int);
-    jint *dstkPtr = _env->GetIntArrayElements(_dstk, NULL);
-    jint dstfLen = _env->GetArrayLength(_dstf) * sizeof(int);
-    jint *dstfPtr = _env->GetIntArrayElements(_dstf, NULL);
-    jint typesLen = _env->GetArrayLength(_types) * sizeof(int);
-    jint *typesPtr = _env->GetIntArrayElements(_types, NULL);
+    jint kernelsLen = _env->GetArrayLength(_kernels);
+    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, NULL);
+    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
+    for(int i = 0; i < kernelsLen; ++i) {
+        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
+    }
 
-    int id = (int)rsScriptGroupCreate((RsContext)con,
-                               (RsScriptKernelID *)kernelsPtr, kernelsLen,
-                               (RsScriptKernelID *)srcPtr, srcLen,
-                               (RsScriptKernelID *)dstkPtr, dstkLen,
-                               (RsScriptFieldID *)dstfPtr, dstfLen,
-                               (RsType *)typesPtr, typesLen);
+    jint srcLen = _env->GetArrayLength(_src);
+    jlong *jSrcPtr = _env->GetLongArrayElements(_src, NULL);
+    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
+    for(int i = 0; i < srcLen; ++i) {
+        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
+    }
 
-    _env->ReleaseIntArrayElements(_kernels, kernelsPtr, 0);
-    _env->ReleaseIntArrayElements(_src, srcPtr, 0);
-    _env->ReleaseIntArrayElements(_dstk, dstkPtr, 0);
-    _env->ReleaseIntArrayElements(_dstf, dstfPtr, 0);
-    _env->ReleaseIntArrayElements(_types, typesPtr, 0);
+    jint dstkLen = _env->GetArrayLength(_dstk);
+    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, NULL);
+    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
+    for(int i = 0; i < dstkLen; ++i) {
+        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
+    }
+
+    jint dstfLen = _env->GetArrayLength(_dstf);
+    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, NULL);
+    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
+    for(int i = 0; i < dstfLen; ++i) {
+        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
+    }
+
+    jint typesLen = _env->GetArrayLength(_types);
+    jlong *jTypesPtr = _env->GetLongArrayElements(_types, NULL);
+    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
+    for(int i = 0; i < typesLen; ++i) {
+        typesPtr[i] = (RsType)jTypesPtr[i];
+    }
+
+    jlong id = (jlong)rsScriptGroupCreate((RsContext)con,
+                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
+                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
+                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
+                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
+                               (RsType *)typesPtr, typesLen * sizeof(RsType));
+
+    free(kernelsPtr);
+    free(srcPtr);
+    free(dstkPtr);
+    free(dstfPtr);
+    free(typesPtr);
+    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
+    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
+    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
+    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
+    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
     return id;
 }
 
@@ -1292,10 +1333,10 @@
 
 static jlong
 nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
-                       jobjectArray texNames, jintArray params)
+                       jobjectArray texNames, jlongArray params)
 {
     AutoJavaStringToUTF8 shaderUTF(_env, shader);
-    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
+    jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
     jint paramLen = _env->GetArrayLength(params);
 
     int texCount = _env->GetArrayLength(texNames);
@@ -1305,11 +1346,16 @@
 
     LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
 
+    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
+    for(int i = 0; i < paramLen; ++i) {
+        paramPtr[i] = (uintptr_t)jParamPtr[i];
+    }
     jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
                                              nameArray, texCount, sizeArray,
-                                             (uint32_t *)paramPtr, paramLen);
+                                             paramPtr, paramLen);
 
-    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
+    free(paramPtr);
+    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
     return ret;
 }
 
@@ -1318,10 +1364,10 @@
 
 static jlong
 nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
-                     jobjectArray texNames, jintArray params)
+                     jobjectArray texNames, jlongArray params)
 {
     AutoJavaStringToUTF8 shaderUTF(_env, shader);
-    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
+    jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
     jint paramLen = _env->GetArrayLength(params);
 
     LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
@@ -1331,11 +1377,17 @@
     const char ** nameArray = names.c_str();
     size_t* sizeArray = names.c_str_len();
 
+    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
+    for(int i = 0; i < paramLen; ++i) {
+        paramPtr[i] = (uintptr_t)jParamPtr[i];
+    }
+
     jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
                                            nameArray, texCount, sizeArray,
-                                           (uint32_t *)paramPtr, paramLen);
+                                           paramPtr, paramLen);
 
-    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
+    free(paramPtr);
+    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
     return ret;
 }
 
@@ -1416,24 +1468,36 @@
 }
 
 static jlong
-nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jintArray _vtx, jintArray _idx, jintArray _prim)
+nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
 {
     LOG_API("nMeshCreate, con(%p)", (RsContext)con);
 
     jint vtxLen = _env->GetArrayLength(_vtx);
-    jint *vtxPtr = _env->GetIntArrayElements(_vtx, NULL);
+    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, NULL);
+    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
+    for(int i = 0; i < vtxLen; ++i) {
+        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
+    }
+
     jint idxLen = _env->GetArrayLength(_idx);
-    jint *idxPtr = _env->GetIntArrayElements(_idx, NULL);
+    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, NULL);
+    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
+    for(int i = 0; i < idxLen; ++i) {
+        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
+    }
+
     jint primLen = _env->GetArrayLength(_prim);
     jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
 
-    int id = (int)rsMeshCreate((RsContext)con,
+    jlong id = (jlong)rsMeshCreate((RsContext)con,
                                (RsAllocation *)vtxPtr, vtxLen,
                                (RsAllocation *)idxPtr, idxLen,
                                (uint32_t *)primPtr, primLen);
 
-    _env->ReleaseIntArrayElements(_vtx, vtxPtr, 0);
-    _env->ReleaseIntArrayElements(_idx, idxPtr, 0);
+    free(vtxPtr);
+    free(idxPtr);
+    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
+    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
     _env->ReleaseIntArrayElements(_prim, primPtr, 0);
     return id;
 }
@@ -1457,7 +1521,7 @@
 }
 
 static void
-nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jintArray _ids, int numVtxIDs)
+nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
 {
     LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
 
@@ -1465,14 +1529,15 @@
     rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
 
     for(jint i = 0; i < numVtxIDs; i ++) {
-        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
+        const jlong alloc = (jlong)allocs[i];
+        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
     }
 
     free(allocs);
 }
 
 static void
-nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
+nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
 {
     LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
 
@@ -1482,8 +1547,10 @@
     rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
 
     for(jint i = 0; i < numIndices; i ++) {
-        _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
-        _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]);
+        const jlong alloc = (jlong)allocs[i];
+        const jint prim = (jint)prims[i];
+        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
+        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
     }
 
     free(allocs);
@@ -1536,14 +1603,14 @@
 {"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
 
 {"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
-{"rsnElementCreate2",                "(J[I[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
+{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
 {"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
-{"rsnElementGetSubElements",         "(JJ[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
+{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
 
 {"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
-{"rsnTypeGetNativeData",             "(JJ[I)V",                               (void*)nTypeGetNativeData },
+{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
 
-{"rsnAllocationCreateTyped",         "(JJIII)J",                               (void*)nAllocationCreateTyped },
+{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
 {"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
 {"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
 {"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
@@ -1594,7 +1661,7 @@
 {"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
 {"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
 {"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
-{"rsnScriptGroupCreate",             "(J[I[I[I[I[I)J",                        (void*)nScriptGroupCreate },
+{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
 {"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
 {"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
 {"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
@@ -1605,9 +1672,9 @@
 {"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
 {"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
 
-{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[I)J",              (void*)nProgramFragmentCreate },
+{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
 {"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
-{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[I)J",              (void*)nProgramVertexCreate },
+{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
 
 {"rsnContextBindRootScript",         "(JI)V",                                 (void*)nContextBindRootScript },
 {"rsnContextBindProgramStore",       "(JI)V",                                 (void*)nContextBindProgramStore },
@@ -1618,12 +1685,12 @@
 {"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
 
 {"rsnPathCreate",                    "(JIZJJF)J",                             (void*)nPathCreate },
-{"rsnMeshCreate",                    "(J[I[I[I)J",                            (void*)nMeshCreate },
+{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
 
 {"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
 {"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
-{"rsnMeshGetVertices",               "(JJ[II)V",                              (void*)nMeshGetVertices },
-{"rsnMeshGetIndices",                "(JJ[I[II)V",                            (void*)nMeshGetIndices },
+{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
+{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
 
 };
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 186ae1b..8eaefef 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -5803,19 +5803,25 @@
             return;
         }
 
+        boolean skip = false;
+
         long restoreSet = getAvailableRestoreToken(packageName);
         if (DEBUG) Slog.v(TAG, "restoreAtInstall pkg=" + packageName
                 + " token=" + Integer.toHexString(token)
                 + " restoreSet=" + Long.toHexString(restoreSet));
+        if (restoreSet == 0) {
+            if (MORE_DEBUG) Slog.i(TAG, "No restore set");
+            skip = true;
+        }
 
-        if (mAutoRestore && mProvisioned && restoreSet != 0) {
-            // Do we have a transport to fetch data for us?
-            IBackupTransport transport = getTransport(mCurrentTransport);
-            if (transport == null) {
-                if (DEBUG) Slog.w(TAG, "No transport for install-time restore");
-                return;
-            }
+        // Do we have a transport to fetch data for us?
+        IBackupTransport transport = getTransport(mCurrentTransport);
+        if (transport == null) {
+            if (DEBUG) Slog.w(TAG, "No transport");
+            skip = true;
+        }
 
+        if (!skip && mAutoRestore && mProvisioned) {
             try {
                 // okay, we're going to attempt a restore of this package from this restore set.
                 // The eventual message back into the Package Manager to run the post-install
@@ -5837,12 +5843,15 @@
                 mBackupHandler.sendMessage(msg);
             } catch (RemoteException e) {
                 // Binding to the transport broke; back off and proceed with the installation.
-                Slog.e(TAG, "Unable to contact transport for install-time restore");
+                Slog.e(TAG, "Unable to contact transport");
+                skip = true;
             }
-        } else {
+        }
+
+        if (skip) {
             // Auto-restore disabled or no way to attempt a restore; just tell the Package
             // Manager to proceed with the post-install handling for this package.
-            if (DEBUG) Slog.v(TAG, "No restore set -- skipping restore");
+            if (DEBUG) Slog.v(TAG, "Skipping");
             try {
                 mPackageManagerBinder.finishPackageInstall(token);
             } catch (RemoteException e) { /* can't happen */ }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e534a88..f03a8e0 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -492,7 +492,7 @@
 
         PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
-        
+
         mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0,
                 new Intent(Intent.ACTION_TIME_TICK).addFlags(
                         Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -1283,13 +1283,7 @@
                                 setWakelockWorkSource(alarm.operation, alarm.workSource);
                                 mWakeLock.setUnimportantForLogging(
                                         alarm.operation == mTimeTickSender);
-                                // XXX debugging
-                                /*
-                                Intent intent = alarm.operation.getIntent();
-                                mWakeLock.setTag(intent.getAction() != null ? intent.getAction()
-                                        : (intent.getComponent() != null
-                                                ? intent.getComponent().toShortString() : TAG));
-                                */
+                                mWakeLock.setHistoryTag(alarm.operation.getTag("*alarm*:"));
                                 mWakeLock.acquire();
                             }
                             final InFlight inflight = new InFlight(AlarmManagerService.this,
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 6e72e24..cb5946a 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -108,6 +108,7 @@
     private final Object mLock = new Object();
 
     private BatteryProperties mBatteryProps;
+    private final BatteryProperties mLastBatteryProps = new BatteryProperties();
     private boolean mBatteryLevelCritical;
     private int mLastBatteryStatus;
     private int mLastBatteryHealth;
@@ -281,6 +282,8 @@
                 mBatteryProps = props;
                 // Process the new values.
                 processValuesLocked();
+            } else {
+                mLastBatteryProps.set(props);
             }
         }
     }
@@ -617,6 +620,9 @@
                 String key = args[1];
                 String value = args[2];
                 try {
+                    if (!mUpdatesStopped) {
+                        mLastBatteryProps.set(mBatteryProps);
+                    }
                     boolean update = true;
                     if ("ac".equals(key)) {
                         mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
@@ -649,13 +655,17 @@
             } else if (args.length == 1 && "reset".equals(args[0])) {
                 long ident = Binder.clearCallingIdentity();
                 try {
-                    mUpdatesStopped = false;
+                    if (mUpdatesStopped) {
+                        mUpdatesStopped = false;
+                        mBatteryProps.set(mLastBatteryProps);
+                        processValuesLocked();
+                    }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
             } else {
                 pw.println("Dump current battery state, or:");
-                pw.println("  set ac|usb|wireless|status|level|invalid <value>");
+                pw.println("  set [ac|usb|wireless|status|level|invalid] <value>");
                 pw.println("  reset");
             }
         }
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 546324a..0d6f548 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1005,7 +1005,7 @@
                         mState = BluetoothAdapter.STATE_OFF;
                         // enable
                         handleEnable(mQuietEnable);
-		    } else if (mBinding || mBluetooth != null) {
+                    } else if (mBinding || mBluetooth != null) {
                         Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
                         userMsg.arg2 = 1 + msg.arg2;
                         // if user is switched when service is being binding
@@ -1014,7 +1014,7 @@
                         if (DBG) {
                             Log.d(TAG, "delay MESSAGE_USER_SWITCHED " + userMsg.arg2);
                         }
-		    }
+                    }
                     break;
                 }
             }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 36907ed..d5c2a0f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1986,7 +1986,9 @@
         mNetTrackers[prevNetType].setTeardownRequested(false);
 
         // Remove idletimer previously setup in {@code handleConnect}
-        removeDataActivityTracking(prevNetType);
+        if (mNetConfigs[prevNetType].isDefault()) {
+            removeDataActivityTracking(prevNetType);
+        }
 
         /*
          * If the disconnected network is not the active one, then don't report
@@ -2318,8 +2320,6 @@
     private void handleConnect(NetworkInfo info) {
         final int newNetType = info.getType();
 
-        setupDataActivityTracking(newNetType);
-
         // snapshot isFailover, because sendConnectedBroadcast() resets it
         boolean isFailover = info.isFailover();
         final NetworkStateTracker thisNet = mNetTrackers[newNetType];
@@ -2357,6 +2357,7 @@
                         return;
                 }
             }
+            setupDataActivityTracking(newNetType);
             synchronized (ConnectivityService.this) {
                 // have a new default network, release the transition wakelock in a second
                 // if it's held.  The second pause is to allow apps to reconnect over the
@@ -2406,7 +2407,7 @@
      * Setup data activity tracking for the given network interface.
      *
      * Every {@code setupDataActivityTracking} should be paired with a
-     * {@link removeDataActivityTracking} for cleanup.
+     * {@link #removeDataActivityTracking} for cleanup.
      */
     private void setupDataActivityTracking(int type) {
         final NetworkStateTracker thisNet = mNetTrackers[type];
@@ -2431,7 +2432,7 @@
 
         if (timeout > 0 && iface != null) {
             try {
-                mNetd.addIdleTimer(iface, timeout, Integer.toString(type));
+                mNetd.addIdleTimer(iface, timeout, type);
             } catch (RemoteException e) {
             }
         }
@@ -2944,6 +2945,9 @@
             }
         }
 
+        pw.print("Active default network: "); pw.println(getNetworkTypeName(mActiveDefaultNetwork));
+        pw.println();
+
         pw.println("Network Requester Pids:");
         pw.increaseIndent();
         for (int net : mPriorityList) {
@@ -3641,8 +3645,7 @@
             int user = UserHandle.getUserId(Binder.getCallingUid());
             if (ConnectivityManager.isNetworkTypeValid(type) && mNetTrackers[type] != null) {
                 synchronized(mVpns) {
-                    mVpns.get(user).protect(socket,
-                            mNetTrackers[type].getLinkProperties().getInterfaceName());
+                    mVpns.get(user).protect(socket);
                 }
                 return true;
             }
diff --git a/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java b/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java
index 6fbf713..0cf9dcd 100644
--- a/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java
+++ b/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java
@@ -20,5 +20,6 @@
 interface INativeDaemonConnectorCallbacks {
 
     void onDaemonConnected();
+    boolean onCheckHoldWakeLock(int code);
     boolean onEvent(int code, String raw, String[] cooked);
 }
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index fc68205..1eedaae 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1790,10 +1790,6 @@
 
     @Override
     public boolean isProviderEnabled(String provider) {
-        // TODO: remove this check in next release, see b/10696351
-        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
-                provider);
-
         // Fused provider is accessed indirectly via criteria rather than the provider-based APIs,
         // so we discourage its use
         if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 607def6..a7ef424 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -817,6 +817,13 @@
     /**
      * Callback from NativeDaemonConnector
      */
+    public boolean onCheckHoldWakeLock(int code) {
+        return false;
+    }
+
+    /**
+     * Callback from NativeDaemonConnector
+     */
     public boolean onEvent(int code, String raw, String[] cooked) {
         if (DEBUG_EVENTS) {
             StringBuilder builder = new StringBuilder();
@@ -1407,7 +1414,8 @@
          * amount of containers we'd ever expect to have. This keeps an
          * "asec list" from blocking a thread repeatedly.
          */
-        mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25);
+        mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25,
+                null);
 
         Thread thread = new Thread(mConnector, VOLD_TAG);
         thread.start();
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index 417d6d8..265b957 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -21,6 +21,7 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.LocalLog;
 import android.util.Slog;
@@ -56,6 +57,8 @@
 
     private final ResponseQueue mResponseQueue;
 
+    private final PowerManager.WakeLock mWakeLock;
+
     private INativeDaemonConnectorCallbacks mCallbacks;
     private Handler mCallbackHandler;
 
@@ -70,10 +73,14 @@
     private final int BUFFER_SIZE = 4096;
 
     NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
-            int responseQueueSize, String logTag, int maxLogSize) {
+            int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl) {
         mCallbacks = callbacks;
         mSocket = socket;
         mResponseQueue = new ResponseQueue(responseQueueSize);
+        mWakeLock = wl;
+        if (mWakeLock != null) {
+            mWakeLock.setReferenceCounted(true);
+        }
         mSequenceNumber = new AtomicInteger(0);
         TAG = logTag != null ? logTag : "NativeDaemonConnector";
         mLocalLog = new LocalLog(maxLogSize);
@@ -102,6 +109,10 @@
             }
         } catch (Exception e) {
             loge("Error handling '" + event + "': " + e);
+        } finally {
+            if (mCallbacks.onCheckHoldWakeLock(msg.what)) {
+                mWakeLock.release();
+            }
         }
         return true;
     }
@@ -154,18 +165,29 @@
                                 buffer, start, i - start, StandardCharsets.UTF_8);
                         log("RCV <- {" + rawEvent + "}");
 
+                        boolean releaseWl = false;
                         try {
                             final NativeDaemonEvent event = NativeDaemonEvent.parseRawEvent(
                                     rawEvent);
                             if (event.isClassUnsolicited()) {
                                 // TODO: migrate to sending NativeDaemonEvent instances
-                                mCallbackHandler.sendMessage(mCallbackHandler.obtainMessage(
-                                        event.getCode(), event.getRawEvent()));
+                                if (mCallbacks.onCheckHoldWakeLock(event.getCode())) {
+                                    mWakeLock.acquire();
+                                    releaseWl = true;
+                                }
+                                if (mCallbackHandler.sendMessage(mCallbackHandler.obtainMessage(
+                                        event.getCode(), event.getRawEvent()))) {
+                                    releaseWl = false;
+                                }
                             } else {
                                 mResponseQueue.add(event.getCmdNumber(), event);
                             }
                         } catch (IllegalArgumentException e) {
                             log("Problem parsing message: " + rawEvent + " - " + e);
+                        } finally {
+                            if (releaseWl) {
+                                mWakeLock.acquire();
+                            }
                         }
 
                         start = i + 1;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 74de577..bfc966b 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -37,6 +37,7 @@
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetworkManagementEventObserver;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
@@ -48,7 +49,9 @@
 import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Handler;
+import android.os.INetworkActivityListener;
 import android.os.INetworkManagementService;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -81,7 +84,6 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -175,12 +177,12 @@
     /** Set of interfaces with active idle timers. */
     private static class IdleTimerParams {
         public final int timeout;
-        public final String label;
+        public final int type;
         public int networkCount;
 
-        IdleTimerParams(int timeout, String label) {
+        IdleTimerParams(int timeout, int type) {
             this.timeout = timeout;
-            this.label = label;
+            this.type = type;
             this.networkCount = 1;
         }
     }
@@ -189,6 +191,10 @@
     private volatile boolean mBandwidthControlEnabled;
     private volatile boolean mFirewallEnabled;
 
+    private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
+            new RemoteCallbackList<INetworkActivityListener>();
+    private boolean mNetworkActive;
+
     /**
      * Constructs a new NetworkManagementService instance
      *
@@ -201,8 +207,11 @@
             return;
         }
 
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NETD_TAG);
+
         mConnector = new NativeDaemonConnector(
-                new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160);
+                new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl);
         mThread = new Thread(mConnector, NETD_TAG);
 
         // Add ourself to the Watchdog monitors.
@@ -337,20 +346,38 @@
     /**
      * Notify our observers of a change in the data activity state of the interface
      */
-    private void notifyInterfaceClassActivity(String label, boolean active) {
+    private void notifyInterfaceClassActivity(int type, boolean active) {
         try {
-            getBatteryStats().noteDataConnectionActive(label, active);
+            getBatteryStats().noteDataConnectionActive(type, active);
         } catch (RemoteException e) {
         }
+
         final int length = mObservers.beginBroadcast();
         for (int i = 0; i < length; i++) {
             try {
-                mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active);
+                mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(
+                        Integer.toString(type), active);
             } catch (RemoteException e) {
             } catch (RuntimeException e) {
             }
         }
         mObservers.finishBroadcast();
+
+        boolean report = false;
+        synchronized (mIdleTimerLock) {
+            if (mActiveIdleTimers.isEmpty()) {
+                // If there are no idle times, we are not monitoring activity, so we
+                // are always considered active.
+                active = true;
+            }
+            if (mNetworkActive != active) {
+                mNetworkActive = active;
+                report = active;
+            }
+        }
+        if (report) {
+            reportNetworkActive();
+        }
     }
 
     /**
@@ -488,6 +515,11 @@
         }
 
         @Override
+        public boolean onCheckHoldWakeLock(int code) {
+            return code == NetdResponseCode.InterfaceClassActivity;
+        }
+
+        @Override
         public boolean onEvent(int code, String raw, String[] cooked) {
             String errorMessage = String.format("Invalid event from daemon (%s)", raw);
             switch (code) {
@@ -540,7 +572,7 @@
                         throw new IllegalStateException(errorMessage);
                     }
                     boolean isActive = cooked[2].equals("active");
-                    notifyInterfaceClassActivity(cooked[3], isActive);
+                    notifyInterfaceClassActivity(Integer.parseInt(cooked[3]), isActive);
                     return true;
                     // break;
             case NetdResponseCode.InterfaceAddressChange:
@@ -1202,7 +1234,7 @@
     }
 
     @Override
-    public void addIdleTimer(String iface, int timeout, String label) {
+    public void addIdleTimer(String iface, int timeout, final int type) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         if (DBG) Slog.d(TAG, "Adding idletimer");
@@ -1216,13 +1248,22 @@
             }
 
             try {
-                mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
+                mConnector.execute("idletimer", "add", iface, Integer.toString(timeout),
+                        Integer.toString(type));
             } catch (NativeDaemonConnectorException e) {
                 throw e.rethrowAsParcelableException();
             }
-            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
+            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
+
             // Networks start up.
-            notifyInterfaceClassActivity(label, true);
+            if (ConnectivityManager.isNetworkTypeMobile(type)) {
+                mNetworkActive = false;
+            }
+            mMainHandler.post(new Runnable() {
+                @Override public void run() {
+                    notifyInterfaceClassActivity(type, true);
+                }
+            });
         }
     }
 
@@ -1233,18 +1274,23 @@
         if (DBG) Slog.d(TAG, "Removing idletimer");
 
         synchronized (mIdleTimerLock) {
-            IdleTimerParams params = mActiveIdleTimers.get(iface);
+            final IdleTimerParams params = mActiveIdleTimers.get(iface);
             if (params == null || --(params.networkCount) > 0) {
                 return;
             }
 
             try {
                 mConnector.execute("idletimer", "remove", iface,
-                        Integer.toString(params.timeout), params.label);
+                        Integer.toString(params.timeout), Integer.toString(params.type));
             } catch (NativeDaemonConnectorException e) {
                 throw e.rethrowAsParcelableException();
             }
             mActiveIdleTimers.remove(iface);
+            mMainHandler.post(new Runnable() {
+                @Override public void run() {
+                    notifyInterfaceClassActivity(params.type, false);
+                }
+            });
         }
     }
 
@@ -1803,6 +1849,35 @@
         return event.getMessage().endsWith("started");
     }
 
+    @Override
+    public void registerNetworkActivityListener(INetworkActivityListener listener) {
+        mNetworkActivityListeners.register(listener);
+    }
+
+    @Override
+    public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
+        mNetworkActivityListeners.unregister(listener);
+    }
+
+    @Override
+    public boolean isNetworkActive() {
+        synchronized (mNetworkActivityListeners) {
+            return mNetworkActive || mActiveIdleTimers.isEmpty();
+        }
+    }
+
+    private void reportNetworkActive() {
+        final int length = mNetworkActivityListeners.beginBroadcast();
+        for (int i = 0; i < length; i++) {
+            try {
+                mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
+            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
+            }
+        }
+        mNetworkActivityListeners.finishBroadcast();
+    }
+
     /** {@inheritDoc} */
     @Override
     public void monitor() {
@@ -1836,6 +1911,17 @@
             pw.println("]");
         }
 
+        synchronized (mIdleTimerLock) {
+            pw.println("Idle timers:");
+            for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
+                pw.print("  "); pw.print(ent.getKey()); pw.println(":");
+                IdleTimerParams params = ent.getValue();
+                pw.print("    timeout="); pw.print(params.timeout);
+                pw.print(" type="); pw.print(params.type);
+                pw.print(" networkCount="); pw.println(params.networkCount);
+            }
+        }
+
         pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
     }
 }
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 74633ae..c9f9a25 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -534,7 +534,7 @@
         mContentResolver = context.getContentResolver();
 
         mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
-                MDNS_TAG, 25);
+                MDNS_TAG, 25, null);
 
         mNsdStateMachine = new NsdStateMachine(TAG);
         mNsdStateMachine.start();
@@ -622,6 +622,10 @@
             mNativeDaemonConnected.countDown();
         }
 
+        public boolean onCheckHoldWakeLock(int code) {
+            return false;
+        }
+
         public boolean onEvent(int code, String raw, String[] cooked) {
             // TODO: NDC translates a message to a callback, we could enhance NDC to
             // directly interact with a state machine through messages
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7b2fc50..f8d7821 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5547,6 +5547,38 @@
     }
 
     @Override
+    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
+        if (!(pendingResult instanceof PendingIntentRecord)) {
+            return null;
+        }
+        try {
+            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
+            Intent intent = res.key.requestIntent;
+            if (intent != null) {
+                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
+                        || res.lastTagPrefix.equals(prefix))) {
+                    return res.lastTag;
+                }
+                res.lastTagPrefix = prefix;
+                StringBuilder sb = new StringBuilder(128);
+                if (prefix != null) {
+                    sb.append(prefix);
+                }
+                if (intent.getAction() != null) {
+                    sb.append(intent.getAction());
+                } else if (intent.getComponent() != null) {
+                    intent.getComponent().appendShortString(sb);
+                } else {
+                    sb.append("?");
+                }
+                return res.lastTag = sb.toString();
+            }
+        } catch (ClassCastException e) {
+        }
+        return null;
+    }
+
+    @Override
     public void setProcessLimit(int max) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessLimit()");
@@ -7107,6 +7139,15 @@
     }
 
     @Override
+    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "deleteActivityContainer()");
+        synchronized (this) {
+            mStackSupervisor.deleteActivityContainer(container);
+        }
+    }
+
+    @Override
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
             throws RemoteException {
         synchronized (this) {
@@ -16040,8 +16081,20 @@
 
     // Multi-user methods
 
+    /**
+     * Start user, if its not already running, but don't bring it to foreground.
+     */
+    @Override
+    public boolean startUserInBackground(final int userId) {
+        return startUser(userId, /* foreground */ false);
+    }
+
     @Override
     public boolean switchUser(final int userId) {
+        return startUser(userId, /* foregound */ true);
+    }
+
+    private boolean startUser(final int userId, boolean foreground) {
         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                 != PackageManager.PERMISSION_GRANTED) {
             String msg = "Permission Denial: switchUser() from pid="
@@ -16079,12 +16132,18 @@
                     needStart = true;
                 }
 
-                mCurrentUserId = userId;
                 final Integer userIdInt = Integer.valueOf(userId);
                 mUserLru.remove(userIdInt);
                 mUserLru.add(userIdInt);
 
-                mWindowManager.setCurrentUser(userId);
+                if (foreground) {
+                    mCurrentUserId = userId;
+                    mWindowManager.setCurrentUser(userId);
+                } else {
+                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
+                    mUserLru.remove(currentUserIdInt);
+                    mUserLru.add(currentUserIdInt);
+                }
 
                 // Once the internal notion of the active user has switched, we lock the device
                 // with the option to show the user switcher on the keyguard.
@@ -16109,12 +16168,15 @@
                     needStart = true;
                 }
 
-                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
-                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
-                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
-                        oldUserId, userId, uss));
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
-                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
+                if (foreground) {
+                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
+                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
+                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
+                            oldUserId, userId, uss));
+                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
+                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
+                }
+
                 if (needStart) {
                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -16145,16 +16207,18 @@
                     }
                 }
 
-                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
-                if (homeInFront) {
-                    startHomeActivityLocked(userId);
-                } else {
-                    mStackSupervisor.resumeTopActivitiesLocked();
+                if (foreground) {
+                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
+                    if (homeInFront) {
+                        startHomeActivityLocked(userId);
+                    } else {
+                        mStackSupervisor.resumeTopActivitiesLocked();
+                    }
+                    EventLogTags.writeAmSwitchUser(userId);
+                    getUserManagerLocked().userForeground(userId);
+                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
                 }
 
-                EventLogTags.writeAmSwitchUser(userId);
-                getUserManagerLocked().userForeground(userId);
-                sendUserSwitchBroadcastsLocked(oldUserId, userId);
                 if (needStart) {
                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 98bb357..5d23fc3 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -598,7 +598,7 @@
             int requestCode, int resultCode,
             Intent resultData) {
         ActivityResult r = new ActivityResult(from, resultWho,
-        		requestCode, resultCode, resultData);
+                requestCode, resultCode, resultData);
         if (results == null) {
             results = new ArrayList<ResultInfo>();
         }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 3a837e8..9636de7 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -523,7 +523,7 @@
     }
 
     void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
-		// TODO: Put all stacks in supervisor and iterate through them instead.
+        // TODO: Put all stacks in supervisor and iterate through them instead.
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -2180,13 +2180,28 @@
             ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
             if (top != null) {
                 // TODO: Make sure the next activity doesn't start up when top is destroyed.
-                stack.destroyActivityLocked(top, true, true, "stack removal");
+                stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
             }
             mActivityContainers.removeAt(ndx);
             container.detachLocked();
         }
     }
 
+    void deleteActivityContainer(IActivityContainer container) {
+        ActivityContainer activityContainer = (ActivityContainer)container;
+        if (activityContainer != null) {
+            activityContainer.mStack.destroyActivitiesLocked(null, true,
+                    "deleteActivityContainer");
+            final ActivityRecord parent = activityContainer.mParentActivity;
+            if (parent != null) {
+                parent.mChildContainers.remove(activityContainer);
+            }
+            final int stackId = activityContainer.mStackId;
+            mActivityContainers.remove(stackId);
+            mWindowManager.removeStack(stackId);
+        }
+    }
+
     private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
         ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
         if (activityDisplay == null) {
@@ -2557,6 +2572,7 @@
         pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
         pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
+        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
     }
 
     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 059aa2b..fc7aac2 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -126,11 +126,11 @@
         }
     }
 
-    public void noteStartWakelock(int uid, int pid, String name, int type,
+    public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
             boolean unimportantForLogging) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeLocked(uid, pid, name, type, unimportantForLogging);
+            mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging);
         }
     }
 
@@ -141,11 +141,12 @@
         }
     }
 
-    public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type,
-            boolean unimportantForLogging) {
+    public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
+            String historyName, int type, boolean unimportantForLogging) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeFromSourceLocked(ws, pid, name, type, unimportantForLogging);
+            mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
+                    type, unimportantForLogging);
         }
     }
 
@@ -231,10 +232,10 @@
         }
     }
 
-    public void noteDataConnectionActive(String label, boolean active) {
+    public void noteDataConnectionActive(int type, boolean active) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteDataConnectionActive(label, active);
+            mStats.noteDataConnectionActive(type, active);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 00fa216..98999e9 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -41,6 +41,8 @@
     boolean canceled = false;
 
     String stringName;
+    String lastTagPrefix;
+    String lastTag;
     
     final static class Key {
         final int type;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index af08d57..f4bad73 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -279,13 +279,12 @@
     }
 
     /**
-     * Protect a socket from routing changes by binding it to the given
-     * interface. The socket is NOT closed by this method.
+     * Protect a socket from VPN rules by binding it to the main routing table.
+     * The socket is NOT closed by this method.
      *
      * @param socket The socket to be bound.
-     * @param interfaze The name of the interface.
      */
-    public void protect(ParcelFileDescriptor socket, String interfaze) throws Exception {
+    public void protect(ParcelFileDescriptor socket) throws Exception {
 
         PackageManager pm = mContext.getPackageManager();
         int appUid = pm.getPackageUid(mPackage, mUserId);
@@ -299,8 +298,6 @@
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-        // bind the socket to the interface
-        jniProtect(socket.getFd(), interfaze);
 
     }
 
@@ -679,7 +676,6 @@
     private native int jniSetRoutes(String interfaze, String routes);
     private native void jniReset(String interfaze);
     private native int jniCheck(String interfaze);
-    private native void jniProtect(int socket, String interfaze);
 
     private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) {
         for (RouteInfo route : prop.getAllRoutes()) {
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 0185a21..e43dea9 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -53,6 +53,7 @@
 import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.os.BatteryStats;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -60,6 +61,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -75,6 +77,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.accounts.AccountManagerService;
@@ -151,7 +154,7 @@
 
     private static final int INITIALIZATION_UNBIND_DELAY_MS = 5000;
 
-    private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*";
+    private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/";
     private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm";
     private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock";
 
@@ -172,6 +175,7 @@
 
     private final NotificationManager mNotificationMgr;
     private AlarmManager mAlarmService = null;
+    private final IBatteryStats mBatteryStats;
 
     private SyncStorageEngine mSyncStorageEngine;
 
@@ -435,6 +439,8 @@
         }
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                BatteryStats.SERVICE_NAME));
 
         // This WakeLock is used to ensure that we stay awake between the time that we receive
         // a sync alarm notification and when we finish processing it. We need to do this
@@ -1123,6 +1129,7 @@
         final int mSyncAdapterUid;
         SyncInfo mSyncInfo;
         boolean mIsLinkedToDeath = false;
+        String mEventName;
 
         /**
          * Create an ActiveSyncContext for an impending sync and grab the wakelock for that
@@ -1201,6 +1208,13 @@
                     new UserHandle(mSyncOperation.target.userId));
             if (!bindResult) {
                 mBound = false;
+            } else {
+                try {
+                    mEventName = mSyncOperation.wakeLockName();
+                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_START,
+                            mEventName, mSyncAdapterUid);
+                } catch (RemoteException e) {
+                }
             }
             return bindResult;
         }
@@ -1216,6 +1230,11 @@
             if (mBound) {
                 mBound = false;
                 mContext.unbindService(this);
+                try {
+                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_FINISH,
+                            mEventName, mSyncAdapterUid);
+                } catch (RemoteException e) {
+                }
             }
             mSyncWakeLock.release();
             mSyncWakeLock.setWorkSource(null);
@@ -1908,10 +1927,10 @@
         }
 
         private PowerManager.WakeLock getSyncWakeLock(SyncOperation operation) {
-            final String wakeLockKey = operation.wakeLockKey();
+            final String wakeLockKey = operation.wakeLockName();
             PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey);
             if (wakeLock == null) {
-                final String name = SYNC_WAKE_LOCK_PREFIX + operation.wakeLockName();
+                final String name = SYNC_WAKE_LOCK_PREFIX + wakeLockKey;
                 wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name);
                 wakeLock.setReferenceCounted(false);
                 mWakeLocks.put(wakeLockKey, wakeLock);
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index 036b21f..5233014 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -86,6 +86,9 @@
     /** Amount of time before {@link #effectiveRunTime} from which this sync can run. */
     public long flexTime;
 
+    /** Descriptive string key for this operation */
+    public String wakeLockName;
+
     public SyncOperation(Account account, int userId, int reason, int source, String provider,
             Bundle extras, long runTimeFromNow, long flexTime, long backoff,
             long delayUntil, boolean allowParallelSyncs) {
@@ -308,25 +311,17 @@
         sb.append("]");
     }
 
-    public String wakeLockKey() {
-        if (target.target_provider) {
-            return target.account.name + "/" + target.account.type + ":" + target.provider;
-        } else if (target.target_service) {
-            return target.service.getPackageName() + "/" + target.service.getClassName();
-        } else {
-            Log.wtf(TAG, "Invalid target getting wakelock for operation - " + key);
-            return null;
-        }
-    }
-
     public String wakeLockName() {
+        if (wakeLockName != null) {
+            return wakeLockName;
+        }
         if (target.target_provider) {
-            return "/" + target.provider
+            return (wakeLockName = target.provider
                     + "/" + target.account.type
-                    + "/" + target.account.name;
+                    + "/" + target.account.name);
         } else if (target.target_service) {
-            return "/" + target.service.getPackageName()
-                    + "/" + target.service.getClassName();
+            return (wakeLockName = target.service.getPackageName()
+                    + "/" + target.service.getClassName());
         } else {
             Log.wtf(TAG, "Invalid target getting wakelock name for operation - " + key);
             return null;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 0d3fa84..89acec9 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -17,10 +17,10 @@
 package com.android.server.media;
 
 import android.content.Intent;
-import android.media.IMediaController;
-import android.media.IMediaControllerCallback;
-import android.media.IMediaSession;
-import android.media.IMediaSessionCallback;
+import android.media.session.IMediaController;
+import android.media.session.IMediaControllerCallback;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
 import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.os.IBinder;
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 9c96c35..a7ff926 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -17,9 +17,9 @@
 package com.android.server.media;
 
 import android.content.Context;
-import android.media.IMediaSession;
-import android.media.IMediaSessionCallback;
-import android.media.IMediaSessionManager;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
+import android.media.session.IMediaSessionManager;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.text.TextUtils;
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index df2aaca..243bd74 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -16,6 +16,8 @@
 
 package com.android.server.notification;
 
+import android.os.IBinder;
+
 public interface NotificationDelegate {
     void onSetDisabled(int status);
     void onClearAll();
@@ -24,4 +26,5 @@
     void onNotificationError(String pkg, String tag, int id,
             int uid, int initialPid, String message);
     void onPanelRevealed();
+    boolean allowDisable(int what, IBinder token, String pkg);
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ab46dfe..e37bb9c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -154,7 +154,7 @@
     private long[] mFallbackVibrationPattern;
     boolean mSystemReady;
 
-    int mDisabledNotifications;
+    private boolean mDisableNotificationAlerts;
     NotificationRecord mSoundNotification;
     NotificationRecord mVibrateNotification;
 
@@ -202,6 +202,19 @@
 
     final ArrayList<NotificationScorer> mScorers = new ArrayList<NotificationScorer>();
 
+    private int mZenMode;
+    private int mPreZenAlarmVolume = -1;
+    private int mPreZenRingerMode = -1;
+    // temporary, until we update apps to provide metadata
+    private static final Set<String> CALL_PACKAGES = new HashSet<String>(Arrays.asList(
+            "com.google.android.dialer",
+            "com.android.phone"
+            ));
+    private static final Set<String> ALARM_PACKAGES = new HashSet<String>(Arrays.asList(
+            "com.google.android.deskclock"
+            ));
+    private static final String EXTRA_INTERCEPT = "android.intercept";
+
     private class NotificationListenerInfo implements IBinder.DeathRecipient {
         INotificationListener listener;
         ComponentName component;
@@ -258,10 +271,11 @@
 
         @Override
         public void binderDied() {
-            if (connection == null) {
-                // This is not a service; it won't be recreated. We can give up this connection.
-                unregisterListenerImpl(this.listener, this.userid);
-            }
+            // Remove the listener, but don't unbind from the service. The system will bring the
+            // service back up, and the onServiceConnected handler will readd the listener with the
+            // new binding. If this isn't a bound service, and is just a registered
+            // INotificationListener, just removing it from the list is all we need to do anyway.
+            removeListenerImpl(this.listener, this.userid);
         }
 
         /** convenience method for looking in mEnabledListenersForCurrentUser */
@@ -869,8 +883,8 @@
         @Override
         public void onSetDisabled(int status) {
             synchronized (mNotificationList) {
-                mDisabledNotifications = status;
-                if ((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
+                mDisableNotificationAlerts = (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+                if (mDisableNotificationAlerts) {
                     // cancel whatever's going on
                     long identity = Binder.clearCallingIdentity();
                     try {
@@ -968,6 +982,14 @@
             }
             Binder.restoreCallingIdentity(ident);
         }
+
+        @Override
+        public boolean allowDisable(int what, IBinder token, String pkg) {
+            if (mZenMode == Settings.Global.ZEN_MODE_FULL && isCall(pkg, null)) {
+                return false;
+            }
+            return true;
+        }
     };
 
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -1077,6 +1099,12 @@
         private final Uri ENABLED_NOTIFICATION_LISTENERS_URI
                 = Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
 
+        private final Uri ZEN_MODE
+                = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
+
+        private final Uri MODE_RINGER
+                = Settings.Global.getUriFor(Settings.Global.MODE_RINGER);
+
         SettingsObserver(Handler handler) {
             super(handler);
         }
@@ -1087,6 +1115,10 @@
                     false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(ENABLED_NOTIFICATION_LISTENERS_URI,
                     false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(ZEN_MODE,
+                    false, this);
+            resolver.registerContentObserver(MODE_RINGER,
+                    false, this);
             update(null);
         }
 
@@ -1107,6 +1139,12 @@
             if (uri == null || ENABLED_NOTIFICATION_LISTENERS_URI.equals(uri)) {
                 rebindListenerServices();
             }
+            if (ZEN_MODE.equals(uri)) {
+                updateZenMode();
+            }
+            if (MODE_RINGER.equals(uri)) {
+                updateRingerMode();
+            }
         }
     }
 
@@ -1170,8 +1208,10 @@
         // flag at least once and we'll go back to 0 after that.
         if (0 == Settings.Global.getInt(getContext().getContentResolver(),
                     Settings.Global.DEVICE_PROVISIONED, 0)) {
-            mDisabledNotifications = StatusBarManager.DISABLE_NOTIFICATION_ALERTS;
+            mDisableNotificationAlerts = true;
         }
+        updateRingerMode();
+        updateZenMode();
 
         // register for various Intents
         IntentFilter filter = new IntentFilter();
@@ -1622,8 +1662,10 @@
 
             pw.println("  mSoundNotification=" + mSoundNotification);
             pw.println("  mVibrateNotification=" + mVibrateNotification);
-            pw.println("  mDisabledNotifications=0x"
-                    + Integer.toHexString(mDisabledNotifications));
+            pw.println("  mDisableNotificationAlerts=" + mDisableNotificationAlerts);
+            pw.println("  mZenMode=" + Settings.Global.zenModeToString(mZenMode));
+            pw.println("  mPreZenAlarmVolume=" + mPreZenAlarmVolume);
+            pw.println("  mPreZenRingerMode=" + mPreZenRingerMode);
             pw.println("  mSystemReady=" + mSystemReady);
             pw.println("  mArchive=" + mArchive.toString());
             Iterator<StatusBarNotification> iter = mArchive.descendingIterator();
@@ -1767,9 +1809,13 @@
                     return;
                 }
 
-                // Should this notification make noise, vibe, or use the LED?
-                final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
+                // Is this notification intercepted by zen mode?
+                final boolean intercept = shouldIntercept(pkg, notification);
+                notification.extras.putBoolean(EXTRA_INTERCEPT, intercept);
 
+                // Should this notification make noise, vibe, or use the LED?
+                final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD) && !intercept;
+                if (DBG) Slog.v(TAG, "canInterrupt=" + canInterrupt + " intercept=" + intercept);
                 synchronized (mNotificationList) {
                     final StatusBarNotification n = new StatusBarNotification(
                             pkg, id, tag, callingUid, callingPid, score, notification, user);
@@ -1851,8 +1897,7 @@
                     }
 
                     // If we're not supposed to beep, vibrate, etc. then don't.
-                    if (((mDisabledNotifications
-                            & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
+                    if (!mDisableNotificationAlerts
                             && (!(old != null
                                 && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
                             && (r.getUserId() == UserHandle.USER_ALL ||
@@ -1860,7 +1905,7 @@
                             && canInterrupt
                             && mSystemReady
                             && mAudioManager != null) {
-
+                        if (DBG) Slog.v(TAG, "Interrupting!");
                         // sound
 
                         // should we use the default notification sound? (indicated either by
@@ -1905,6 +1950,8 @@
                                     final IRingtonePlayer player =
                                             mAudioManager.getRingtonePlayer();
                                     if (player != null) {
+                                        if (DBG) Slog.v(TAG, "Playing sound " + soundUri
+                                                + " on stream " + audioStreamType);
                                         player.playAsync(soundUri, user, looping, audioStreamType);
                                     }
                                 } catch (RemoteException e) {
@@ -1999,20 +2046,35 @@
         }
     }
 
+    /**
+     * Removes a listener from the list and unbinds from its service.
+     */
     void unregisterListenerImpl(final INotificationListener listener, final int userid) {
+        NotificationListenerInfo info = removeListenerImpl(listener, userid);
+        if (info != null && info.connection != null) {
+            getContext().unbindService(info.connection);
+        }
+    }
+
+    /**
+     * Removes a listener from the list but does not unbind from the listener's service.
+     *
+     * @return the removed listener.
+     */
+    NotificationListenerInfo removeListenerImpl(
+            final INotificationListener listener, final int userid) {
+        NotificationListenerInfo listenerInfo = null;
         synchronized (mNotificationList) {
             final int N = mListeners.size();
             for (int i=N-1; i>=0; i--) {
                 final NotificationListenerInfo info = mListeners.get(i);
                 if (info.listener.asBinder() == listener.asBinder()
                         && info.userid == userid) {
-                    mListeners.remove(i);
-                    if (info.connection != null) {
-                        getContext().unbindService(info.connection);
-                    }
+                    listenerInfo = mListeners.remove(i);
                 }
             }
         }
+        return listenerInfo;
     }
 
     void showNextToastLocked() {
@@ -2437,4 +2499,67 @@
             updateLightsLocked();
         }
     }
+
+    private void updateRingerMode() {
+        final int ringerMode = Settings.Global.getInt(getContext().getContentResolver(),
+                Settings.Global.MODE_RINGER, -1);
+        final boolean nonSilentRingerMode = ringerMode == AudioManager.RINGER_MODE_NORMAL
+                || ringerMode == AudioManager.RINGER_MODE_VIBRATE;
+        if (mZenMode == Settings.Global.ZEN_MODE_FULL && nonSilentRingerMode) {
+            Settings.Global.putInt(getContext().getContentResolver(),
+                    Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+        }
+    }
+
+    private void updateZenMode() {
+        mZenMode = Settings.Global.getInt(getContext().getContentResolver(),
+                Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+        if (DBG) Slog.d(TAG, "updateZenMode " + Settings.Global.zenModeToString(mZenMode));
+        if (mAudioManager != null) {
+            if (mZenMode == Settings.Global.ZEN_MODE_FULL) {
+                // calls vibrate if ringer mode = vibrate, so set the ringer mode as well
+                mPreZenRingerMode = mAudioManager.getRingerMode();
+                if (DBG) Slog.d(TAG, "Muting calls mPreZenRingerMode=" + mPreZenRingerMode);
+                mAudioManager.setStreamMute(AudioManager.STREAM_RING, true);
+                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+                // alarms don't simply respect mute, so set the volume as well
+                mPreZenAlarmVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
+                if (DBG) Slog.d(TAG, "Muting alarms mPreZenAlarmVolume=" + mPreZenAlarmVolume);
+                mAudioManager.setStreamMute(AudioManager.STREAM_ALARM, true);
+                mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, 0, 0);
+            } else {
+                if (DBG) Slog.d(TAG, "Unmuting calls");
+                mAudioManager.setStreamMute(AudioManager.STREAM_RING, false);
+                if (mPreZenRingerMode != -1) {
+                    if (DBG) Slog.d(TAG, "Restoring ringer mode to " + mPreZenRingerMode);
+                    mAudioManager.setRingerMode(mPreZenRingerMode);
+                    mPreZenRingerMode = -1;
+                }
+                if (DBG) Slog.d(TAG, "Unmuting alarms");
+                mAudioManager.setStreamMute(AudioManager.STREAM_ALARM, false);
+                if (mPreZenAlarmVolume != -1) {
+                    if (DBG) Slog.d(TAG, "Restoring STREAM_ALARM to " + mPreZenAlarmVolume);
+                    mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mPreZenAlarmVolume, 0);
+                    mPreZenAlarmVolume = -1;
+                }
+            }
+        }
+    }
+
+    private boolean isCall(String pkg, Notification n) {
+        return CALL_PACKAGES.contains(pkg);
+    }
+
+    private boolean isAlarm(String pkg, Notification n) {
+        return ALARM_PACKAGES.contains(pkg);
+    }
+
+    private boolean shouldIntercept(String pkg, Notification n) {
+        if (mZenMode == Settings.Global.ZEN_MODE_LIMITED) {
+            return !isCall(pkg, n) && !isAlarm(pkg, n);
+        } else if (mZenMode == Settings.Global.ZEN_MODE_FULL) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 07a74cd..7f00ce7 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3774,6 +3774,7 @@
             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
         }
+        boolean updatedPkgBetter = false;
         // First check if this is a system package that may involve an update
         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
             if (ps != null && !ps.codePath.equals(scanFile)) {
@@ -3828,6 +3829,7 @@
                     synchronized (mPackages) {
                         mSettings.enableSystemPackageLPw(ps.name);
                     }
+                    updatedPkgBetter = true;
                 }
             }
         }
@@ -3904,7 +3906,7 @@
 
         String codePath = null;
         String resPath = null;
-        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
+        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
             if (ps != null && ps.resourcePathString != null) {
                 resPath = ps.resourcePathString;
             } else {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 38a1949..fc98c4e 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -984,27 +984,26 @@
             Slog.w(LOG_TAG, "Only user owner can have related users");
             return null;
         }
-        synchronized (mPackagesLock) {
-            UserInfo relatedUser = getUserInfoLocked(relatedUserId);
-            if (relatedUser == null) {
-                return null;
-            }
-            return createUserInternal(name, flags, relatedUser);
-        }
+        return createUserInternal(name, flags, relatedUserId);
     }
 
     @Override
     public UserInfo createUser(String name, int flags) {
         checkManageUsersPermission("Only the system can create users");
-        return createUserInternal(name, flags, null);
+        return createUserInternal(name, flags, UserHandle.USER_NULL);
     }
 
-    private UserInfo createUserInternal(String name, int flags, UserInfo relatedUser) {
+    private UserInfo createUserInternal(String name, int flags, int relatedUserId) {
         final long ident = Binder.clearCallingIdentity();
-        final UserInfo userInfo;
+        UserInfo userInfo = null;
         try {
             synchronized (mInstallLock) {
                 synchronized (mPackagesLock) {
+                    UserInfo relatedUser = null;
+                    if (relatedUserId != UserHandle.USER_NULL) {
+                        relatedUser = getUserInfoLocked(relatedUserId);
+                        if (relatedUser == null) return null;
+                    }
                     if (isUserLimitReachedLocked()) return null;
                     int userId = getNextAvailableIdLocked();
                     userInfo = new UserInfo(userId, name, null, flags);
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 09be3a8..e1ccf46 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -130,7 +130,7 @@
      * Called when a wake lock is acquired.
      */
     public void onWakeLockAcquired(int flags, String tag, String packageName,
-            int ownerUid, int ownerPid, WorkSource workSource) {
+            int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
         if (DEBUG) {
             Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
                     + "\", packageName=" + packageName
@@ -143,11 +143,11 @@
             boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
                     && ownerUid == Process.SYSTEM_UID;
             if (workSource != null) {
-                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType,
-                        unimportantForLogging);
+                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, historyTag,
+                        monitorType, unimportantForLogging);
             } else {
-                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType,
-                        unimportantForLogging);
+                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+                        monitorType, unimportantForLogging);
                 // XXX need to deal with disabled operations.
                 mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
                         AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 0ba55b6..e7bbf1c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -632,7 +632,7 @@
     }
 
     private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
-            WorkSource ws, int uid, int pid) {
+            WorkSource ws, String historyTag, int uid, int pid) {
         synchronized (mLock) {
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
@@ -647,11 +647,11 @@
                 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
                     // Update existing wake lock.  This shouldn't happen but is harmless.
                     notifyWakeLockReleasedLocked(wakeLock);
-                    wakeLock.updateProperties(flags, tag, packageName, ws, uid, pid);
+                    wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
                     notifyWakeLockAcquiredLocked(wakeLock);
                 }
             } else {
-                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, uid, pid);
+                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
                 try {
                     lock.linkToDeath(wakeLock, 0);
                 } catch (RemoteException ex) {
@@ -786,7 +786,8 @@
         if (mSystemReady) {
             wakeLock.mNotifiedAcquired = true;
             mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
-                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
+                    wakeLock.mHistoryTag);
         }
     }
 
@@ -1553,7 +1554,7 @@
             return false;
         }
         if (!isBeingKeptAwakeLocked()) {
-            if (!mIsPowered && !mDreamsEnabledByDefaultConfig) {
+            if (!mIsPowered && !mDreamsEnabledOnBatteryConfig) {
                 return false;
             }
             if (!mIsPowered
@@ -1590,12 +1591,9 @@
                 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
                 | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
             final int newScreenState = getDesiredScreenPowerStateLocked();
-            if (newScreenState != mDisplayPowerRequest.screenState) {
-                mDisplayPowerRequest.screenState = newScreenState;
-                nativeSetPowerState(
-                        mDisplayPowerRequest.wantScreenOnNormal(),
-                        newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
-            }
+            mDisplayPowerRequest.screenState = newScreenState;
+            nativeSetPowerState(isScreenOnLocked(),
+                    newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
 
             int screenBrightness = mScreenBrightnessSettingDefault;
             float screenAutoBrightnessAdjustment = 0.0f;
@@ -1805,11 +1803,15 @@
 
     private boolean isScreenOnInternal() {
         synchronized (mLock) {
-            return !mSystemReady
-                    || mDisplayPowerRequest.wantScreenOnNormal();
+            return isScreenOnLocked();
         }
     }
 
+    private boolean isScreenOnLocked() {
+        return mWakefulness == WAKEFULNESS_AWAKE
+                || mWakefulness == WAKEFULNESS_DREAMING;
+    }
+
     private void handleBatteryStateChangedLocked() {
         mDirty |= DIRTY_BATTERY_STATE;
         updatePowerStateLocked();
@@ -2274,17 +2276,19 @@
         public String mTag;
         public final String mPackageName;
         public WorkSource mWorkSource;
+        public String mHistoryTag;
         public final int mOwnerUid;
         public final int mOwnerPid;
         public boolean mNotifiedAcquired;
 
         public WakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource workSource, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
             mLock = lock;
             mFlags = flags;
             mTag = tag;
             mPackageName = packageName;
             mWorkSource = copyWorkSource(workSource);
+            mHistoryTag = historyTag;
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
         }
@@ -2304,7 +2308,7 @@
         }
 
         public void updateProperties(int flags, String tag, String packageName,
-                WorkSource workSource, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
             if (!mPackageName.equals(packageName)) {
                 throw new IllegalStateException("Existing wake lock package name changed: "
                         + mPackageName + " to " + packageName);
@@ -2320,6 +2324,7 @@
             mFlags = flags;
             mTag = tag;
             updateWorkSource(workSource);
+            mHistoryTag = historyTag;
         }
 
         public boolean hasSameWorkSource(WorkSource workSource) {
@@ -2517,12 +2522,12 @@
         @Override // Binder call
         public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
                 String packageName, int uid) {
-            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid));
+            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
         }
 
         @Override // Binder call
         public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource ws) {
+                WorkSource ws, String historyTag) {
             if (lock == null) {
                 throw new IllegalArgumentException("lock must not be null");
             }
@@ -2543,7 +2548,7 @@
             final int pid = Binder.getCallingPid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid);
+                acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 2ae467e..8219eb5 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -23,9 +23,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.util.Slog;
@@ -207,6 +205,10 @@
 
     @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);
     }
 
@@ -676,26 +678,4 @@
             }
         }
     }
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
-                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
-                collapsePanels();
-            }
-            /*
-            else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
-                updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
-                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
-            }
-            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
-                updateResources();
-            }
-            */
-        }
-    };
-
 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 68834d8..d4bcd5c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -102,9 +102,8 @@
 
     final WindowManagerService mService;
 
-    static final int DEFER_DETACH = 1;
-    static final int DEFER_REMOVAL = 2;
-    int mDeferredActions;
+    /** Remove this display when animation on it has completed. */
+    boolean mDeferredRemoval;
 
     /**
      * @param display May not be null.
@@ -302,6 +301,49 @@
         }
     }
 
+    boolean isAnimating() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mStacks.get(stackNdx);
+            if (stack.isAnimating()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void checkForDeferredActions() {
+        boolean animating = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final TaskStack stack = mStacks.get(stackNdx);
+            if (stack.isAnimating()) {
+                animating = true;
+            } else {
+                if (stack.mDeferDetach) {
+                    mService.detachStackLocked(this, stack);
+                }
+                final ArrayList<Task> tasks = stack.getTasks();
+                for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                    final Task task = tasks.get(taskNdx);
+                    AppTokenList tokens = task.mAppTokens;
+                    for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                        AppWindowToken wtoken = tokens.get(tokenNdx);
+                        if (wtoken.mDeferRemoval) {
+                            wtoken.mDeferRemoval = false;
+                            mService.removeAppFromTaskLocked(wtoken);
+                        }
+                    }
+                    if (task.mDeferRemoval) {
+                        task.mDeferRemoval = false;
+                        mService.removeTaskLocked(task);
+                    }
+                }
+            }
+        }
+        if (!animating && mDeferredRemoval) {
+            mService.onDisplayRemoved(mDisplayId);
+        }
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
         final String subPrefix = "  " + prefix;
@@ -325,7 +367,8 @@
             pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
             pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
             pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
-            pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
+            pw.print(subPrefix); pw.print("deferred="); pw.print(mDeferredRemoval);
+                pw.print(" layoutNeeded="); pw.println(layoutNeeded);
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             final TaskStack stack = mStacks.get(stackNdx);
             pw.print(prefix); pw.print("mStacks[" + stackNdx + "]"); pw.println(stack.mStackId);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index c70bc62..81db8b3 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -75,6 +75,9 @@
     /** Application tokens that are exiting, but still on screen for animations. */
     final AppTokenList mExitingAppTokens = new AppTokenList();
 
+    /** Detach this stack from its display when animation completes. */
+    boolean mDeferDetach;
+
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
@@ -362,36 +365,9 @@
         mAnimationBackgroundSurface.mDimSurface.destroy();
     }
 
-    void checkForDeferredActions() {
-        if (mDisplayContent != null &&
-                (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
-                !isAnimating()) {
-            mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH;
-            if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) {
-                mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL;
-                mService.onDisplayRemoved(mDisplayContent.getDisplayId());
-            }
-            mService.detachStack(mStackId);
-        }
-        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-            final Task task = mTasks.get(taskNdx);
-            AppTokenList tokens = task.mAppTokens;
-            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
-                AppWindowToken wtoken = tokens.get(tokenNdx);
-                if (wtoken.mDeferRemoval) {
-                    wtoken.mDeferRemoval = false;
-                    mService.removeAppFromTaskLocked(wtoken);
-                }
-            }
-            if (task.mDeferRemoval) {
-                task.mDeferRemoval = false;
-                mService.removeTaskLocked(task);
-            }
-        }
-    }
-
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
+        pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
         for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
             pw.print(prefix); pw.println(mTasks.get(taskNdx));
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f03f9a2..6e1724a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -188,6 +188,7 @@
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
     static final boolean DEBUG_STACK = false;
+    static final boolean DEBUG_DISPLAY = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -4929,6 +4930,11 @@
         }
     }
 
+    void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
+        displayContent.detachStack(stack);
+        stack.detachDisplay();
+    }
+
     public void detachStack(int stackId) {
         synchronized (mWindowMap) {
             TaskStack stack = mStackIdToStack.get(stackId);
@@ -4936,16 +4942,19 @@
                 final DisplayContent displayContent = stack.getDisplayContent();
                 if (displayContent != null) {
                     if (stack.isAnimating()) {
-                        displayContent.mDeferredActions |= DisplayContent.DEFER_DETACH;
+                        stack.mDeferDetach = true;
                         return;
                     }
-                    displayContent.detachStack(stack);
-                    stack.detachDisplay();
+                    detachStackLocked(displayContent, stack);
                 }
             }
         }
     }
 
+    public void removeStack(int stackId) {
+        mStackIdToStack.remove(stackId);
+    }
+
     void removeTaskLocked(Task task) {
         final int taskId = task.taskId;
         final TaskStack stack = task.mStack;
@@ -9501,9 +9510,9 @@
             }
         }
 
-        // Remove all deferred Stacks, tasks, and activities.
-        for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) {
-            mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions();
+        // Remove all deferred displays stacks, tasks, and activities.
+        for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+            mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
         }
 
         setFocusedStackFrame();
@@ -10788,6 +10797,7 @@
     private DisplayContent newDisplayContentLocked(final Display display) {
         DisplayContent displayContent = new DisplayContent(display, this);
         final int displayId = display.getDisplayId();
+        if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display);
         mDisplayContents.put(displayId, displayContent);
 
         DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -10889,10 +10899,11 @@
     private void handleDisplayRemovedLocked(int displayId) {
         final DisplayContent displayContent = getDisplayContentLocked(displayId);
         if (displayContent != null) {
-            if ((displayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0) {
-                displayContent.mDeferredActions |= DisplayContent.DEFER_REMOVAL;
+            if (displayContent.isAnimating()) {
+                displayContent.mDeferredRemoval = true;
                 return;
             }
+            if (DEBUG_DISPLAY) Slog.v(TAG, "Removing display=" + displayContent);
             mDisplayContents.delete(displayId);
             displayContent.close();
             if (displayId == Display.DEFAULT_DISPLAY) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index f98b724..0b19b5c 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -430,7 +430,6 @@
             mService.mPendingRemove.add(mWin);
             mWin.mRemoveOnExit = false;
         }
-        mService.mPendingStacksRemove.add(mWin.getStack());
         mAnimator.hideWallpapersLocked(mWin);
     }
 
@@ -670,10 +669,15 @@
 
             int flags = SurfaceControl.HIDDEN;
             final WindowManager.LayoutParams attrs = mWin.mAttrs;
+            final boolean isVideoPlane =
+                    (attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_VIDEO_PLANE) != 0;
 
             if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
                 flags |= SurfaceControl.SECURE;
             }
+            if (isVideoPlane) {
+                flags |= SurfaceControl.FX_SURFACE_VIDEO_PLANE;
+            }
             if (DEBUG_VISIBILITY) Slog.v(
                 TAG, "Creating surface in session "
                 + mSession.mSurfaceSession + " window " + this
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 7675ba6..56144b0 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -30,7 +30,6 @@
     frameworks/base/libs \
     frameworks/base/core/jni \
     frameworks/native/services \
-    external/skia/include/core \
     libcore/include \
     libcore/include/libsuspend \
 	$(call include-path-for, libhardware)/hardware \
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index fc6de60..bc866d3 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -41,7 +41,11 @@
     jmethodID mConstructor;
 } gParcelFileDescriptorOffsets;
 
-static jmethodID method_usbDeviceAdded;
+static jmethodID method_beginUsbDeviceAdded;
+static jmethodID method_addUsbConfiguration;
+static jmethodID method_addUsbInterface;
+static jmethodID method_addUsbEndpoint;
+static jmethodID method_endUsbDeviceAdded;
 static jmethodID method_usbDeviceRemoved;
 
 static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
@@ -68,64 +72,69 @@
     Vector<int> endpointValues;
     const usb_device_descriptor* deviceDesc = usb_device_get_device_descriptor(device);
 
-    uint16_t vendorId = usb_device_get_vendor_id(device);
-    uint16_t productId = usb_device_get_product_id(device);
-    uint8_t deviceClass = deviceDesc->bDeviceClass;
-    uint8_t deviceSubClass = deviceDesc->bDeviceSubClass;
-    uint8_t protocol = deviceDesc->bDeviceProtocol;
     char *manufacturer = usb_device_get_manufacturer_name(device);
     char *product = usb_device_get_product_name(device);
     char *serial = usb_device_get_serial(device);
 
-    usb_descriptor_iter_init(device, &iter);
-
-    while ((desc = usb_descriptor_iter_next(&iter)) != NULL) {
-        if (desc->bDescriptorType == USB_DT_INTERFACE) {
-            struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
-
-            // push class, subclass, protocol and number of endpoints into interfaceValues vector
-            interfaceValues.add(interface->bInterfaceNumber);
-            interfaceValues.add(interface->bInterfaceClass);
-            interfaceValues.add(interface->bInterfaceSubClass);
-            interfaceValues.add(interface->bInterfaceProtocol);
-            interfaceValues.add(interface->bNumEndpoints);
-        } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
-            struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)desc;
-
-            // push address, attributes, max packet size and interval into endpointValues vector
-            endpointValues.add(endpoint->bEndpointAddress);
-            endpointValues.add(endpoint->bmAttributes);
-            endpointValues.add(__le16_to_cpu(endpoint->wMaxPacketSize));
-            endpointValues.add(endpoint->bInterval);
-        }
-    }
-
-    usb_device_close(device);
-
-    // handle generic device notification
-    int length = interfaceValues.size();
-    jintArray interfaceArray = env->NewIntArray(length);
-    env->SetIntArrayRegion(interfaceArray, 0, length, interfaceValues.array());
-
-    length = endpointValues.size();
-    jintArray endpointArray = env->NewIntArray(length);
-    env->SetIntArrayRegion(endpointArray, 0, length, endpointValues.array());
-
     jstring deviceName = env->NewStringUTF(devname);
     jstring manufacturerName = env->NewStringUTF(manufacturer);
     jstring productName = env->NewStringUTF(product);
     jstring serialNumber = env->NewStringUTF(serial);
-    env->CallVoidMethod(thiz, method_usbDeviceAdded,
-            deviceName, vendorId, productId, deviceClass,
-            deviceSubClass, protocol, manufacturerName,
-            productName, serialNumber, interfaceArray, endpointArray);
 
-    env->DeleteLocalRef(interfaceArray);
-    env->DeleteLocalRef(endpointArray);
+    jboolean result = env->CallBooleanMethod(thiz, method_beginUsbDeviceAdded,
+            deviceName, usb_device_get_vendor_id(device), usb_device_get_product_id(device),
+            deviceDesc->bDeviceClass, deviceDesc->bDeviceSubClass, deviceDesc->bDeviceProtocol,
+            manufacturerName, productName, serialNumber);
+
     env->DeleteLocalRef(serialNumber);
     env->DeleteLocalRef(productName);
     env->DeleteLocalRef(manufacturerName);
     env->DeleteLocalRef(deviceName);
+    free(manufacturer);
+    free(product);
+    free(serial);
+
+    if (!result) goto fail;
+
+    usb_descriptor_iter_init(device, &iter);
+
+    while ((desc = usb_descriptor_iter_next(&iter)) != NULL) {
+        if (desc->bDescriptorType == USB_DT_CONFIG) {
+            struct usb_config_descriptor *config = (struct usb_config_descriptor *)desc;
+            char *name = usb_device_get_string(device, config->iConfiguration);
+            jstring configName = env->NewStringUTF(name);
+
+            env->CallVoidMethod(thiz, method_addUsbConfiguration,
+                    config->bConfigurationValue, configName, config->bmAttributes,
+                    config->bMaxPower);
+
+            env->DeleteLocalRef(configName);
+            free(name);
+        } else if (desc->bDescriptorType == USB_DT_INTERFACE) {
+            struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
+            char *name = usb_device_get_string(device, interface->iInterface);
+            jstring interfaceName = env->NewStringUTF(name);
+
+            env->CallVoidMethod(thiz, method_addUsbInterface,
+                    interface->bInterfaceNumber, interfaceName, interface->bAlternateSetting,
+                    interface->bInterfaceClass, interface->bInterfaceSubClass,
+                    interface->bInterfaceProtocol);
+
+            env->DeleteLocalRef(interfaceName);
+            free(name);
+        } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
+            struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)desc;
+
+            env->CallVoidMethod(thiz, method_addUsbEndpoint,
+                    endpoint->bEndpointAddress, endpoint->bmAttributes,
+                    __le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval);
+        }
+    }
+
+    env->CallVoidMethod(thiz, method_endUsbDeviceAdded);
+
+fail:
+    usb_device_close(device);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
 
     return 0;
@@ -191,12 +200,36 @@
         ALOGE("Can't find com/android/server/usb/UsbHostManager");
         return -1;
     }
-    method_usbDeviceAdded = env->GetMethodID(clazz, "usbDeviceAdded", "(Ljava/lang/String;IIIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I)V");
-    if (method_usbDeviceAdded == NULL) {
-        ALOGE("Can't find usbDeviceAdded");
+    method_beginUsbDeviceAdded = env->GetMethodID(clazz, "beginUsbDeviceAdded",
+            "(Ljava/lang/String;IIIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
+    if (method_beginUsbDeviceAdded == NULL) {
+        ALOGE("Can't find beginUsbDeviceAdded");
         return -1;
     }
-    method_usbDeviceRemoved = env->GetMethodID(clazz, "usbDeviceRemoved", "(Ljava/lang/String;)V");
+    method_addUsbConfiguration = env->GetMethodID(clazz, "addUsbConfiguration",
+            "(ILjava/lang/String;II)V");
+    if (method_addUsbConfiguration == NULL) {
+        ALOGE("Can't find addUsbConfiguration");
+        return -1;
+    }
+    method_addUsbInterface = env->GetMethodID(clazz, "addUsbInterface",
+            "(ILjava/lang/String;IIII)V");
+    if (method_addUsbInterface == NULL) {
+        ALOGE("Can't find addUsbInterface");
+        return -1;
+    }
+    method_addUsbEndpoint = env->GetMethodID(clazz, "addUsbEndpoint", "(IIII)V");
+    if (method_addUsbEndpoint == NULL) {
+        ALOGE("Can't find addUsbEndpoint");
+        return -1;
+    }
+    method_endUsbDeviceAdded = env->GetMethodID(clazz, "endUsbDeviceAdded", "()V");
+    if (method_endUsbDeviceAdded == NULL) {
+        ALOGE("Can't find endUsbDeviceAdded");
+        return -1;
+    }
+    method_usbDeviceRemoved = env->GetMethodID(clazz, "usbDeviceRemoved",
+            "(Ljava/lang/String;)V");
     if (method_usbDeviceRemoved == NULL) {
         ALOGE("Can't find usbDeviceRemoved");
         return -1;
@@ -205,7 +238,8 @@
     clazz = env->FindClass("android/os/ParcelFileDescriptor");
     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
     gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
-    gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
+    gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>",
+            "(Ljava/io/FileDescriptor;)V");
     LOG_FATAL_IF(gParcelFileDescriptorOffsets.mConstructor == NULL,
                  "Unable to find constructor for android.os.ParcelFileDescriptor");
 
diff --git a/services/core/jni/com_android_server_connectivity_Vpn.cpp b/services/core/jni/com_android_server_connectivity_Vpn.cpp
index ab8c959..bf34a74 100644
--- a/services/core/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/core/jni/com_android_server_connectivity_Vpn.cpp
@@ -302,15 +302,6 @@
     return ifr4.ifr_flags;
 }
 
-static int bind_to_interface(int socket, const char *name)
-{
-    if (setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))) {
-        ALOGE("Cannot bind socket to %s: %s", name, strerror(errno));
-        return SYSTEM_ERROR;
-    }
-    return 0;
-}
-
 //------------------------------------------------------------------------------
 
 static void throwException(JNIEnv *env, int error, const char *message)
@@ -433,19 +424,6 @@
     return flags;
 }
 
-static void protect(JNIEnv *env, jobject thiz, jint socket, jstring jName)
-{
-    const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
-    if (!name) {
-        jniThrowNullPointerException(env, "name");
-        return;
-    }
-    if (bind_to_interface(socket, name) < 0) {
-        throwException(env, SYSTEM_ERROR, "Cannot protect socket");
-    }
-    env->ReleaseStringUTFChars(jName, name);
-}
-
 //------------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -455,7 +433,6 @@
     {"jniSetRoutes", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setRoutes},
     {"jniReset", "(Ljava/lang/String;)V", (void *)reset},
     {"jniCheck", "(Ljava/lang/String;)I", (void *)check},
-    {"jniProtect", "(ILjava/lang/String;)V", (void *)protect},
 };
 
 int register_android_server_connectivity_Vpn(JNIEnv *env)
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 83dbbb2..91d77fb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -851,9 +851,8 @@
                 }
             }
 
-            if (!disableNonCoreServices
-                    && context.getResources().getBoolean(R.bool.config_dreamsSupported)) {
-                // Dreams (interactive idle-time views, a/k/a screen savers)
+            if (!disableNonCoreServices) {
+                // Dreams (interactive idle-time views, a/k/a screen savers, and doze mode)
                 mSystemServiceManager.startService(DreamManagerService.class);
             }
 
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 8ae3824..0f20dde 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -226,9 +226,9 @@
                 final Handler handler) {
         }
 
-		@Override
-		public void invalidateCache(int userId) {
-		}
+        @Override
+        public void invalidateCache(int userId) {
+        }
     }
 
     static public class MyMockContext extends MockContext {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index d5dd9a6..b925856 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -99,6 +99,13 @@
     // which need debouncing.
     private static final int UPDATE_DELAY = 1000;
 
+    // Time we received a request to enter USB accessory mode
+    private long mAccessoryModeRequestTime = 0;
+
+    // Timeout for entering USB request mode.
+    // Request is cancelled if host does not configure device within 10 seconds.
+    private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000;
+
     private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
 
     private UsbHandler mHandler;
@@ -206,6 +213,8 @@
     }
 
     private void startAccessoryMode() {
+        if (!mHasUsbAccessory) return;
+
         mAccessoryStrings = nativeGetAccessoryStrings();
         boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
         // don't start accessory mode if our mandatory strings have not been set
@@ -224,6 +233,7 @@
         }
 
         if (functions != null) {
+            mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
             setCurrentFunctions(functions, false);
         }
     }
@@ -452,6 +462,8 @@
         }
 
         private void setEnabledFunctions(String functions, boolean makeDefault) {
+            if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions
+                    + " makeDefault: " + makeDefault);
 
             // Do not update persystent.sys.usb.config if the device is booted up
             // with OEM specific mode.
@@ -513,9 +525,17 @@
         }
 
         private void updateCurrentAccessory() {
-            if (!mHasUsbAccessory) return;
+            // We are entering accessory mode if we have received a request from the host
+            // and the request has not timed out yet.
+            boolean enteringAccessoryMode =
+                    mAccessoryModeRequestTime > 0 &&
+                        SystemClock.elapsedRealtime() <
+                            mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT;
 
-            if (mConfigured) {
+            if (mConfigured && enteringAccessoryMode) {
+                // successfully entered accessory mode
+                mAccessoryModeRequestTime = 0;
+
                 if (mAccessoryStrings != null) {
                     mCurrentAccessory = new UsbAccessory(mAccessoryStrings);
                     Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
@@ -526,7 +546,7 @@
                 } else {
                     Slog.e(TAG, "nativeGetAccessoryStrings failed");
                 }
-            } else if (!mConnected) {
+            } else if (!enteringAccessoryMode) {
                 // make sure accessory mode is off
                 // and restore default functions
                 Slog.d(TAG, "exited USB accessory mode");
@@ -556,6 +576,8 @@
                 }
             }
 
+            if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " connected: " + mConnected
+                                    + " configured: " + mConfigured);
             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
         }
 
@@ -595,9 +617,7 @@
                     if (containsFunction(mCurrentFunctions,
                             UsbManager.USB_FUNCTION_ACCESSORY)) {
                         updateCurrentAccessory();
-                    }
-
-                    if (!mConnected) {
+                    } else if (!mConnected) {
                         // restore defaults when USB is disconnected
                         setEnabledFunctions(mDefaultFunctions, false);
                     }
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index dfaad0b..7ae5460 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -17,6 +17,7 @@
 package com.android.server.usb;
 
 import android.content.Context;
+import android.hardware.usb.UsbConfiguration;
 import android.hardware.usb.UsbConstants;
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbEndpoint;
@@ -30,6 +31,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 
 /**
@@ -48,6 +50,13 @@
     private final Context mContext;
     private final Object mLock = new Object();
 
+    private UsbDevice mNewDevice;
+    private UsbConfiguration mNewConfiguration;
+    private UsbInterface mNewInterface;
+    private ArrayList<UsbConfiguration> mNewConfigurations;
+    private ArrayList<UsbInterface> mNewInterfaces;
+    private ArrayList<UsbEndpoint> mNewEndpoints;
+
     @GuardedBy("mLock")
     private UsbSettingsManager mCurrentSettings;
 
@@ -93,69 +102,103 @@
         return false;
     }
 
-    /* Called from JNI in monitorUsbHostBus() to report new USB devices */
-    private void usbDeviceAdded(String deviceName, int vendorID, int productID,
+    /* Called from JNI in monitorUsbHostBus() to report new USB devices
+       Returns true if successful, in which case the JNI code will continue adding configurations,
+       interfaces and endpoints, and finally call endUsbDeviceAdded after all descriptors
+       have been processed
+     */
+    private boolean beginUsbDeviceAdded(String deviceName, int vendorID, int productID,
             int deviceClass, int deviceSubclass, int deviceProtocol,
-            String manufacturerName, String productName, String serialNumber,
-            /* array of quintuples containing id, class, subclass, protocol
-               and number of endpoints for each interface */
-            int[] interfaceValues,
-           /* array of quadruples containing address, attributes, max packet size
-              and interval for each endpoint */
-            int[] endpointValues) {
+            String manufacturerName, String productName, String serialNumber) {
 
         if (isBlackListed(deviceName) ||
                 isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) {
-            return;
+            return false;
         }
 
         synchronized (mLock) {
             if (mDevices.get(deviceName) != null) {
                 Slog.w(TAG, "device already on mDevices list: " + deviceName);
-                return;
+                return false;
             }
 
-            int numInterfaces = interfaceValues.length / 5;
-            Parcelable[] interfaces = new UsbInterface[numInterfaces];
-            try {
-                // repackage interfaceValues as an array of UsbInterface
-                int intf, endp, ival = 0, eval = 0;
-                for (intf = 0; intf < numInterfaces; intf++) {
-                    int interfaceId = interfaceValues[ival++];
-                    int interfaceClass = interfaceValues[ival++];
-                    int interfaceSubclass = interfaceValues[ival++];
-                    int interfaceProtocol = interfaceValues[ival++];
-                    int numEndpoints = interfaceValues[ival++];
-
-                    Parcelable[] endpoints = new UsbEndpoint[numEndpoints];
-                    for (endp = 0; endp < numEndpoints; endp++) {
-                        int address = endpointValues[eval++];
-                        int attributes = endpointValues[eval++];
-                        int maxPacketSize = endpointValues[eval++];
-                        int interval = endpointValues[eval++];
-                        endpoints[endp] = new UsbEndpoint(address, attributes,
-                                maxPacketSize, interval);
-                    }
-
-                    // don't allow if any interfaces are blacklisted
-                    if (isBlackListed(interfaceClass, interfaceSubclass, interfaceProtocol)) {
-                        return;
-                    }
-                    interfaces[intf] = new UsbInterface(interfaceId, interfaceClass,
-                            interfaceSubclass, interfaceProtocol, endpoints);
-                }
-            } catch (Exception e) {
-                // beware of index out of bound exceptions, which might happen if
-                // a device does not set bNumEndpoints correctly
-                Slog.e(TAG, "error parsing USB descriptors", e);
-                return;
+            if (mNewDevice != null) {
+                Slog.e(TAG, "mNewDevice is not null in endUsbDeviceAdded");
+                return false;
             }
 
-            UsbDevice device = new UsbDevice(deviceName, vendorID, productID,
+            mNewDevice = new UsbDevice(deviceName, vendorID, productID,
                     deviceClass, deviceSubclass, deviceProtocol,
-                    manufacturerName, productName, serialNumber, interfaces);
-            mDevices.put(deviceName, device);
-            getCurrentSettings().deviceAttached(device);
+                    manufacturerName, productName, serialNumber);
+
+            mNewConfigurations = new ArrayList<UsbConfiguration>();
+            mNewInterfaces = new ArrayList<UsbInterface>();
+            mNewEndpoints = new ArrayList<UsbEndpoint>();
+        }
+        return true;
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to report new USB configuration for the device
+       currently being added.  Returns true if successful, false in case of error.
+     */
+    private void addUsbConfiguration(int id, String name, int attributes, int maxPower) {
+        if (mNewConfiguration != null) {
+            mNewConfiguration.setInterfaces(
+                    mNewInterfaces.toArray(new UsbInterface[mNewInterfaces.size()]));
+            mNewInterfaces.clear();
+        }
+
+        mNewConfiguration = new UsbConfiguration(id, name, attributes, maxPower);
+        mNewConfigurations.add(mNewConfiguration);
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to report new USB interface for the device
+       currently being added.  Returns true if successful, false in case of error.
+     */
+    private void addUsbInterface(int id, String name, int altSetting,
+            int Class, int subClass, int protocol) {
+        if (mNewInterface != null) {
+            mNewInterface.setEndpoints(
+                    mNewEndpoints.toArray(new UsbEndpoint[mNewEndpoints.size()]));
+            mNewEndpoints.clear();
+        }
+
+        mNewInterface = new UsbInterface(id, altSetting, name, Class, subClass, protocol);
+        mNewInterfaces.add(mNewInterface);
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to report new USB endpoint for the device
+       currently being added.  Returns true if successful, false in case of error.
+     */
+    private void addUsbEndpoint(int address, int attributes, int maxPacketSize, int interval) {
+        mNewEndpoints.add(new UsbEndpoint(address, attributes, maxPacketSize, interval));
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to finish adding a new device */
+    private void endUsbDeviceAdded() {
+        if (mNewInterface != null) {
+            mNewInterface.setEndpoints(
+                    mNewEndpoints.toArray(new UsbEndpoint[mNewEndpoints.size()]));
+        }
+        if (mNewConfiguration != null) {
+            mNewConfiguration.setInterfaces(
+                    mNewInterfaces.toArray(new UsbInterface[mNewInterfaces.size()]));
+        }
+
+        synchronized (mLock) {
+            if (mNewDevice != null) {
+                mNewDevice.setConfigurations(
+                        mNewConfigurations.toArray(new UsbConfiguration[mNewConfigurations.size()]));
+                mDevices.put(mNewDevice.getDeviceName(), mNewDevice);
+                Slog.d(TAG, "Added device " + mNewDevice);
+                getCurrentSettings().deviceAttached(mNewDevice);
+            } else {
+                Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
+            }
+            mNewDevice = null;
+            mNewConfigurations = null;
+            mNewInterfaces = null;
+            mNewEndpoints = null;
         }
     }
 
diff --git a/test-runner/src/junit/runner/FailureDetailView.java b/test-runner/src/junit/runner/FailureDetailView.java
index 1b8365a..c846191 100644
--- a/test-runner/src/junit/runner/FailureDetailView.java
+++ b/test-runner/src/junit/runner/FailureDetailView.java
@@ -12,7 +12,7 @@
 public interface FailureDetailView {
     // The following definition was removed for compatibility with Android
     // libraries.
-    // 	/**
+    //  /**
     //   * Returns the component used to present the TraceView
     //   */
     //  public Component getComponent();
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
index ef885e3..ec02d34 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
@@ -117,7 +117,7 @@
         }
 
         @Override
-	public void execute(CommandStack stack) {
+        public void execute(CommandStack stack) {
             Filter filter = null;
             try {
                 filter = stack.getFactory().createFilterByClassName(mClassName,
diff --git a/tests/HwAccelerationTest/res/layout/isolation.xml b/tests/HwAccelerationTest/res/layout/isolation.xml
index 802ac7f..32eb628 100644
--- a/tests/HwAccelerationTest/res/layout/isolation.xml
+++ b/tests/HwAccelerationTest/res/layout/isolation.xml
@@ -5,13 +5,15 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="#f55">
+    <!-- Left and right layouts are not isolated volumes, so the text views
+         will interleave since they share an isolated z volume-->
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <LinearLayout
             android:layout_width="0dp"
-            android:layout_height="150dp"
+            android:layout_height="200dp"
             android:layout_weight="1"
             android:isolatedZVolume="false"
             android:orientation="vertical">
@@ -20,21 +22,24 @@
         </LinearLayout>
         <LinearLayout
             android:layout_width="0dp"
-            android:layout_height="150dp"
+            android:layout_height="200dp"
             android:layout_weight="1"
+            android:translationY="50dp"
             android:isolatedZVolume="false"
             android:orientation="vertical">
             <TextView style="@style/TopRightReorderTextView"/>
             <TextView style="@style/BottomRightReorderTextView"/>
         </LinearLayout>
     </LinearLayout>
+
+    <!-- Left and right volumes are isolated by default, so no interleaving will be seen. -->
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <LinearLayout
             android:layout_width="0dp"
-            android:layout_height="150dp"
+            android:layout_height="200dp"
             android:layout_weight="1"
             android:orientation="vertical">
             <TextView style="@style/TopLeftReorderTextView"/>
@@ -42,8 +47,9 @@
         </LinearLayout>
         <LinearLayout
             android:layout_width="0dp"
-            android:layout_height="150dp"
+            android:layout_height="200dp"
             android:layout_weight="1"
+            android:translationY="50dp"
             android:orientation="vertical">
             <TextView style="@style/TopRightReorderTextView"/>
             <TextView style="@style/BottomRightReorderTextView"/>
diff --git a/tests/HwAccelerationTest/res/values/styles.xml b/tests/HwAccelerationTest/res/values/styles.xml
index 0ffd3d7..cde5d20 100644
--- a/tests/HwAccelerationTest/res/values/styles.xml
+++ b/tests/HwAccelerationTest/res/values/styles.xml
@@ -1,14 +1,14 @@
 <resources>
     <style name="ReorderTextView" parent="@android:style/TextAppearance.Medium">
         <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">75dp</item>
+        <item name="android:layout_height">100dp</item>
         <item name="android:gravity">center</item>
     </style>
     <style name="LeftReorderTextView" parent="@style/ReorderTextView">
-        <item name="android:translationX">50dp</item>
+        <item name="android:translationX">20dp</item>
     </style>
     <style name="RightReorderTextView" parent="@style/ReorderTextView">
-        <item name="android:translationX">-50dp</item>
+        <item name="android:translationX">-20dp</item>
     </style>
 
     <style name="TopLeftReorderTextView" parent="@style/LeftReorderTextView">
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
index 25ac2f0..299e6bb 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
@@ -81,11 +81,11 @@
         
         /* Uri Edit Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_URI, 
-        		R.string.uri_edit_text_label));
+                R.string.uri_edit_text_label));
         
         /* Email Address Edit Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS, 
-        		R.string.email_address_edit_text_label));
+                R.string.email_address_edit_text_label));
         
         /* Email Subject Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT, 
@@ -142,7 +142,7 @@
     private View buildEntryView(int inputType, int label) {
 
         
-    	View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
+        View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
         
         EditText editText = (EditText) view.findViewById(R.id.data);
         editText.setInputType(inputType);
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
index a1c5fd2..2db11c5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
@@ -24,26 +24,26 @@
 
 public class BigEditTextActivityNonScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityNonScrollablePanScan> {
 
-	public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
-	
+    public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
+    
     public BigEditTextActivityNonScrollablePanScanTests() {
         super(BigEditTextActivityNonScrollablePanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {
-	    // Give the IME 2 seconds to appear.
-	    pause(2000);
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {
+        // Give the IME 2 seconds to appear.
+        pause(2000);
         
-	    View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
-	    View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
-	        
-	    assertNotNull(rootView);
-	    assertNotNull(servedView);
-	    
-	    destructiveCheckImeInitialState(rootView, servedView);
-	    
+        View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
+        View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
+            
+        assertNotNull(rootView);
+        assertNotNull(servedView);
+        
+        destructiveCheckImeInitialState(rootView, servedView);
+        
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
index 2e0b0eb..1050794 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
@@ -24,14 +24,14 @@
 
 public class BigEditTextActivityNonScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityNonScrollableResize> {
 
-	public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
-	
+    public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
+    
     public BigEditTextActivityNonScrollableResizeTests() {
         super(BigEditTextActivityNonScrollableResize.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityNonScrollableResize) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
index d3eefb5..1e848b0 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
@@ -24,14 +24,14 @@
 
 public class BigEditTextActivityScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityScrollablePanScan> {
 
-	public final String TAG = "BigEditTextActivityScrollablePanScanTests";
-	
+    public final String TAG = "BigEditTextActivityScrollablePanScanTests";
+    
     public BigEditTextActivityScrollablePanScanTests() {
         super(BigEditTextActivityScrollablePanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityScrollablePanScan) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
index 5c40e6d..de607d6 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
@@ -24,15 +24,15 @@
 
 public class BigEditTextActivityScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityScrollableResize> {
 
-	public final String TAG = "BigEditTextActivityScrollableResizeTests";
-	
+    public final String TAG = "BigEditTextActivityScrollableResizeTests";
+    
     public BigEditTextActivityScrollableResizeTests() {
         super(BigEditTextActivityScrollableResize.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       
-	    // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       
+        // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityScrollableResize) mTargetActivity).getRootView();
@@ -44,6 +44,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
index 9a93133..c521905 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
@@ -24,14 +24,14 @@
 
 public class BottomEditTextActivityPanScanTests extends ImfBaseTestCase<BottomEditTextActivityPanScan> {
 
-	public final String TAG = "BottomEditTextActivityPanScanTests";
-	
+    public final String TAG = "BottomEditTextActivityPanScanTests";
+    
     public BottomEditTextActivityPanScanTests() {
         super(BottomEditTextActivityPanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {
         // Give the IME 2 seconds to appear.
         pause(2000);
         
@@ -44,6 +44,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
         
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
index ae900c3..f6f97b5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
@@ -23,8 +23,8 @@
 
 public class ButtonActivityTest extends ImfBaseTestCase<ButtonActivity> {
 
-	final public String TAG = "ButtonActivityTest";
-	
+    final public String TAG = "ButtonActivityTest";
+    
     public ButtonActivityTest() {
         super(ButtonActivity.class);
     }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
index ed5b0c9..6147d3c 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
@@ -22,21 +22,21 @@
 
 public class OneEditTextActivityNotSelectedTests extends ImfBaseTestCase<OneEditTextActivityNotSelected> {
 
-	public final String TAG = "OneEditTextActivityNotSelectedTests";
-	
+    public final String TAG = "OneEditTextActivityNotSelectedTests";
+    
     public OneEditTextActivityNotSelectedTests() {
         super(OneEditTextActivityNotSelected.class);
     }
     
-	@LargeTest
-	public void testSoftKeyboardNoAutoPop() {
-	    
-	    // Give the IME 2 seconds to appear.
-	    pause(2000);
-	    
-	    assertFalse(mImm.isAcceptingText());
-	    
-	    View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
+    @LargeTest
+    public void testSoftKeyboardNoAutoPop() {
+        
+        // Give the IME 2 seconds to appear.
+        pause(2000);
+        
+        assertFalse(mImm.isAcceptingText());
+        
+        View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
         View servedView = ((OneEditTextActivityNotSelected) mTargetActivity).getDefaultFocusedView();
         
         assertNotNull(rootView);
@@ -45,6 +45,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
         
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
index 9bc3baa..2b14384 100644
--- a/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
+++ b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
@@ -12,10 +12,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 package com.android.onemedia;
 
-import android.media.MediaSessionToken;
+import android.media.session.MediaSessionToken;
 
 interface IPlayerCallback {
     void onSessionChanged(in MediaSessionToken session);
diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
index ab1d3fc..efdbe9a 100644
--- a/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
+++ b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
@@ -12,17 +12,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 package com.android.onemedia;
 
-import android.media.MediaSessionToken;
+import android.media.session.MediaSessionToken;
 import android.os.Bundle;
 
 import com.android.onemedia.IPlayerCallback;
 import com.android.onemedia.playback.IRequestCallback;
 
 interface IPlayerService {
-    MediaSessionToken getSessionToken(); 
+    MediaSessionToken getSessionToken();
     void registerCallback(in IPlayerCallback cb);
     void unregisterCallback(in IPlayerCallback cb);
     void sendRequest(String action, in Bundle params, in IRequestCallback cb);
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
index 4ccc846..3f15db5 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
@@ -1,8 +1,8 @@
 
 package com.android.onemedia;
 
-import android.media.MediaController;
-import android.media.MediaSessionManager;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerService.java b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
index 0819077..0b2ba8f 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerService.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
@@ -2,7 +2,7 @@
 
 import android.app.Service;
 import android.content.Intent;
-import android.media.MediaSessionToken;
+import android.media.session.MediaSessionToken;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index 25a8f0d..e5fb0d0 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -2,9 +2,9 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.media.MediaSession;
-import android.media.MediaSessionManager;
-import android.media.MediaSessionToken;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionToken;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.KeyEvent;
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index cceed16..3bd35a7 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -37,7 +37,7 @@
     }
 
     @SmallTest
-	public void testREORDER_TASKS() {
+    public void testREORDER_TASKS() {
         try {
             mAm.moveTaskToFront(0, 0, null);
             fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
@@ -67,7 +67,7 @@
         } catch (RemoteException e) {
             fail("Unexpected remote exception");
         }
-	}
+    }
 
     @SmallTest
     public void testCHANGE_CONFIGURATION() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
index 4dfe0fe..322b853 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
@@ -32,7 +32,7 @@
  */
 public class ServiceManagerPermissionTests extends TestCase {
     @SmallTest
-	public void testAddService() {
+    public void testAddService() {
         try {
             // The security in the service manager is that you can't replace
             // a service that is already published.
@@ -43,7 +43,7 @@
         } catch (SecurityException e) {
             // expected
         }
-	}
+    }
 
     @SmallTest
     public void testSetPermissionController() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index df32ee1..6f5788a 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -41,7 +41,7 @@
     }
 
     @SmallTest
-	public void testMANAGE_APP_TOKENS() {
+    public void testMANAGE_APP_TOKENS() {
         try {
             mWm.pauseKeyDispatching(null);
             fail("IWindowManager.pauseKeyDispatching did not throw SecurityException as"
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index cbeaae8..49b8b55 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -59,10 +59,10 @@
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
-          mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
-          mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
-          mUseCrunchCache(false), mErrorOnFailedInsert(false), mErrorOnMissingConfigEntry(false),
-          mOutputTextSymbols(NULL),
+          mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL),
+          mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false),
+          mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false),
+          mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL),
           mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),
           mArgc(0), mArgv(NULL)
         {}
@@ -166,6 +166,8 @@
     void setVersionCode(const char*  val) { mVersionCode = val; }
     const char* getVersionName() const { return mVersionName; }
     void setVersionName(const char* val) { mVersionName = val; }
+    bool getReplaceVersion() { return mReplaceVersion; }
+    void setReplaceVersion(bool val) { mReplaceVersion = val; }
     const char* getCustomPackage() const { return mCustomPackage; }
     void setCustomPackage(const char* val) { mCustomPackage = val; }
     const char* getExtraPackages() const { return mExtraPackages; }
@@ -285,6 +287,7 @@
     const char* mMaxSdkVersion;
     const char* mVersionCode;
     const char* mVersionName;
+    bool        mReplaceVersion;
     const char* mCustomPackage;
     const char* mExtraPackages;
     const char* mMaxResVersion;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 1ed4630..33711fa 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -153,6 +153,11 @@
         "       inserts android:versionCode in to manifest.\n"
         "   --version-name\n"
         "       inserts android:versionName in to manifest.\n"
+        "   --replace-version\n"
+        "       If --version-code and/or --version-name are specified, these\n"
+        "       values will replace any value already in the manifest. By\n"
+        "       default, nothing is changed if the manifest already defines\n"
+        "       these attributes.\n"
         "   --custom-package\n"
         "       generates R.java into a different package.\n"
         "   --extra-packages\n"
@@ -532,6 +537,8 @@
                         goto bail;
                     }
                     bundle.setVersionName(argv[0]);
+                } else if (strcmp(cp, "-replace-version") == 0) {
+                    bundle.setReplaceVersion(true);
                 } else if (strcmp(cp, "-values") == 0) {
                     bundle.setValues(true);
                 } else if (strcmp(cp, "-include-meta-data") == 0) {
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index c923bc2..6d9d62e 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -676,13 +676,15 @@
 }
 
 /*
- * Inserts an attribute in a given node, only if the attribute does not
- * exist.
+ * Inserts an attribute in a given node.
  * If errorOnFailedInsert is true, and the attribute already exists, returns false.
- * Returns true otherwise, even if the attribute already exists.
+ * If replaceExisting is true, the attribute will be updated if it already exists.
+ * Returns true otherwise, even if the attribute already exists, and does not modify
+ * the existing attribute's value.
  */
 bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
-        const char* attr8, const char* value, bool errorOnFailedInsert)
+        const char* attr8, const char* value, bool errorOnFailedInsert,
+        bool replaceExisting)
 {
     if (value == NULL) {
         return true;
@@ -691,7 +693,16 @@
     const String16 ns(ns8);
     const String16 attr(attr8);
 
-    if (node->getAttribute(ns, attr) != NULL) {
+    XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);
+    if (existingEntry != NULL) {
+        if (replaceExisting) {
+            NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);"
+                         " overwriting existing value from manifest.\n",
+                         String8(attr).string(), String8(ns).string()));
+            existingEntry->string = String16(value);
+            return true;
+        }
+
         if (errorOnFailedInsert) {
             fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
                             " cannot insert new value %s.\n",
@@ -711,6 +722,18 @@
     return true;
 }
 
+/*
+ * Inserts an attribute in a given node, only if the attribute does not
+ * exist.
+ * If errorOnFailedInsert is true, and the attribute already exists, returns false.
+ * Returns true otherwise, even if the attribute already exists.
+ */
+bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
+        const char* attr8, const char* value, bool errorOnFailedInsert)
+{
+    return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false);
+}
+
 static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
         const String16& attrName) {
     XMLNode::attribute_entry* attr = node->editAttribute(
@@ -748,13 +771,14 @@
     }
 
     bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
+    bool replaceVersion = bundle->getReplaceVersion();
 
     if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
-            bundle->getVersionCode(), errorOnFailedInsert)) {
+            bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) {
         return UNKNOWN_ERROR;
     }
     if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
-            bundle->getVersionName(), errorOnFailedInsert)) {
+            bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {
         return UNKNOWN_ERROR;
     }
     
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 2e4274d..aef3efa 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -1,12 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
+	<classpathentry kind="src" path="tests/src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
index fd594f7..5f0d98b 100644
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
@@ -33,11 +33,6 @@
     private static long sBootTime = System.currentTimeMillis();
     private static long sBootTimeNano = System.nanoTime();
 
-    @LayoutlibDelegate
-    /*package*/ static boolean setCurrentTimeMillis(long millis) {
-        return true;
-    }
-
     /**
      * Returns milliseconds since boot, not counting time spent in deep sleep.
      * <b>Note:</b> This value may get reset occasionally (before it would
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 281337c..a90632c 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -39,7 +39,7 @@
     }
 
     @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3)
+    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
             throws RemoteException {
         // pass for now.
     }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index a79fba1..2ef3d5f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -114,6 +114,7 @@
                         "android.os.*",  // for android.os.Handler
                         "android.database.ContentObserver", // for Digital clock
                         "com.android.i18n.phonenumbers.*",  // for TextView with autolink attribute
+                        "android.app.DatePickerDialog",     // b.android.com/28318
                     },
                     excludeClasses,
                     new String[] {
diff --git a/tools/preload/Android.mk b/tools/preload/Android.mk
index f325870..14a4547 100644
--- a/tools/preload/Android.mk
+++ b/tools/preload/Android.mk
@@ -20,4 +20,4 @@
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
-include $(call all-subdir-makefiles)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 4a6b1ff..84e933d 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -20,6 +20,8 @@
 import android.net.wifi.BatchedScanSettings;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.ScanSettings;
+import android.net.wifi.WifiChannel;
 import android.net.wifi.ScanResult;
 import android.net.DhcpInfo;
 
@@ -45,7 +47,9 @@
 
     boolean pingSupplicant();
 
-    void startScan(in WorkSource ws);
+    List<WifiChannel> getChannelList();
+
+    void startScan(in ScanSettings requested, in WorkSource ws);
 
     List<ScanResult> getScanResults(String callingPackage);
 
diff --git a/wifi/java/android/net/wifi/ScanSettings.aidl b/wifi/java/android/net/wifi/ScanSettings.aidl
new file mode 100644
index 0000000..ebd2a39
--- /dev/null
+++ b/wifi/java/android/net/wifi/ScanSettings.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.wifi;
+
+parcelable ScanSettings;
diff --git a/wifi/java/android/net/wifi/ScanSettings.java b/wifi/java/android/net/wifi/ScanSettings.java
new file mode 100644
index 0000000..094ce34
--- /dev/null
+++ b/wifi/java/android/net/wifi/ScanSettings.java
@@ -0,0 +1,87 @@
+/*
+ * 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.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Bundle of customized scan settings
+ *
+ * @see WifiManager#startCustomizedScan
+ *
+ * @hide
+ */
+public class ScanSettings implements Parcelable {
+
+    /** channel set to scan. this can be null or empty, indicating a full scan */
+    public Collection<WifiChannel> channelSet;
+
+    /** public constructor */
+    public ScanSettings() { }
+
+    /** copy constructor */
+    public ScanSettings(ScanSettings source) {
+        if (source.channelSet != null)
+            channelSet = new ArrayList<WifiChannel>(source.channelSet);
+    }
+
+    /** check for validity */
+    public boolean isValid() {
+        for (WifiChannel channel : channelSet)
+            if (!channel.isValid()) return false;
+        return true;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(channelSet == null ? 0 : channelSet.size());
+        if (channelSet != null)
+            for (WifiChannel channel : channelSet) channel.writeToParcel(out, flags);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<ScanSettings> CREATOR =
+            new Parcelable.Creator<ScanSettings>() {
+        @Override
+        public ScanSettings createFromParcel(Parcel in) {
+            ScanSettings settings = new ScanSettings();
+            int size = in.readInt();
+            if (size > 0) {
+                settings.channelSet = new ArrayList<WifiChannel>(size);
+                while (size-- > 0)
+                    settings.channelSet.add(WifiChannel.CREATOR.createFromParcel(in));
+            }
+            return settings;
+        }
+
+        @Override
+        public ScanSettings[] newArray(int size) {
+            return new ScanSettings[size];
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/WifiChannel.aidl b/wifi/java/android/net/wifi/WifiChannel.aidl
new file mode 100644
index 0000000..c3d06bd
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiChannel.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.wifi;
+
+parcelable WifiChannel;
diff --git a/wifi/java/android/net/wifi/WifiChannel.java b/wifi/java/android/net/wifi/WifiChannel.java
new file mode 100644
index 0000000..640481e
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiChannel.java
@@ -0,0 +1,87 @@
+/*
+ * 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.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Wifi Channel
+ *
+ * @see ScanSettings
+ *
+ * @hide
+ */
+public class WifiChannel implements Parcelable {
+
+    private static final int MIN_FREQ_MHZ = 2412;
+    private static final int MAX_FREQ_MHZ = 5825;
+
+    private static final int MIN_CHANNEL_NUM = 1;
+    private static final int MAX_CHANNEL_NUM = 196;
+
+    /** frequency */
+    public int freqMHz;
+
+    /** channel number */
+    public int channelNum;
+
+    /** is it a DFS channel? */
+    public boolean isDFS;
+
+    /** public constructor */
+    public WifiChannel() { }
+
+    /** check for validity */
+    public boolean isValid() {
+        if (freqMHz < MIN_FREQ_MHZ || freqMHz > MAX_FREQ_MHZ) return false;
+        if (channelNum < MIN_CHANNEL_NUM || channelNum > MAX_CHANNEL_NUM) return false;
+        return true;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(freqMHz);
+        out.writeInt(channelNum);
+        out.writeInt(isDFS ? 1 : 0);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<WifiChannel> CREATOR =
+            new Parcelable.Creator<WifiChannel>() {
+        @Override
+        public WifiChannel createFromParcel(Parcel in) {
+            WifiChannel channel = new WifiChannel();
+            channel.freqMHz = in.readInt();
+            channel.channelNum = in.readInt();
+            channel.isDFS = in.readInt() != 0;
+            return channel;
+        }
+
+        @Override
+        public WifiChannel[] newArray(int size) {
+            return new WifiChannel[size];
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 6a13067..4a6821c 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -69,6 +69,10 @@
     public static final String LINK_SPEED_UNITS = "Mbps";
     private int mLinkSpeed;
 
+    /** Frequency in MHz */
+    public static final String FREQUENCY_UNITS = "MHz";
+    private int mFrequency;
+
     private InetAddress mIpAddress;
     private String mMacAddress;
 
@@ -86,6 +90,7 @@
         mSupplicantState = SupplicantState.UNINITIALIZED;
         mRssi = -9999;
         mLinkSpeed = -1;
+        mFrequency = -1;
     }
 
     /**
@@ -100,6 +105,7 @@
             mNetworkId = source.mNetworkId;
             mRssi = source.mRssi;
             mLinkSpeed = source.mLinkSpeed;
+            mFrequency = source.mFrequency;
             mIpAddress = source.mIpAddress;
             mMacAddress = source.mMacAddress;
             mMeteredHint = source.mMeteredHint;
@@ -179,6 +185,20 @@
     }
 
     /**
+     * Returns the current frequency in {@link #FREQUENCY_UNITS}.
+     * @return the frequency.
+     * @see #FREQUENCY_UNITS
+     */
+    public int getFrequency() {
+        return mFrequency;
+    }
+
+    /** @hide */
+    public void setFrequency(int frequency) {
+        this.mFrequency = frequency;
+    }
+
+    /**
      * Record the MAC address of the WLAN interface
      * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
      * @hide
@@ -303,7 +323,8 @@
             append(", Supplicant state: ").
             append(mSupplicantState == null ? none : mSupplicantState).
             append(", RSSI: ").append(mRssi).
-            append(", Link speed: ").append(mLinkSpeed).
+            append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS).
+            append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS).
             append(", Net ID: ").append(mNetworkId).
             append(", Metered hint: ").append(mMeteredHint);
 
@@ -320,6 +341,7 @@
         dest.writeInt(mNetworkId);
         dest.writeInt(mRssi);
         dest.writeInt(mLinkSpeed);
+        dest.writeInt(mFrequency);
         if (mIpAddress != null) {
             dest.writeByte((byte)1);
             dest.writeByteArray(mIpAddress.getAddress());
@@ -346,6 +368,7 @@
                 info.setNetworkId(in.readInt());
                 info.setRssi(in.readInt());
                 info.setLinkSpeed(in.readInt());
+                info.setFrequency(in.readInt());
                 if (in.readByte() == 1) {
                     try {
                         info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index aabe007..0862b7e 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -20,6 +20,8 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.net.DhcpInfo;
+import android.net.wifi.ScanSettings;
+import android.net.wifi.WifiChannel;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Handler;
@@ -763,6 +765,22 @@
     }
 
     /**
+     * Get a list of available channels for customized scan.
+     *
+     * @see {@link WifiChannel}
+     *
+     * @return the channel list, or null if not available
+     * @hide
+     */
+    public List<WifiChannel> getChannelList() {
+        try {
+            return mService.getChannelList();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Request a scan for access points. Returns immediately. The availability
      * of the results is made known later by means of an asynchronous event sent
      * on completion of the scan.
@@ -770,8 +788,7 @@
      */
     public boolean startScan() {
         try {
-            final WorkSource workSource = null;
-            mService.startScan(workSource);
+            mService.startScan(null, null);
             return true;
         } catch (RemoteException e) {
             return false;
@@ -781,7 +798,42 @@
     /** @hide */
     public boolean startScan(WorkSource workSource) {
         try {
-            mService.startScan(workSource);
+            mService.startScan(null, workSource);
+            return true;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Request a scan for access points in specified channel list. Each channel is specified by its
+     * frequency in MHz, e.g. "5500" (do NOT include "DFS" even though it is). The availability of
+     * the results is made known later in the same way as {@link #startScan}.
+     *
+     * Note:
+     *
+     * 1. Customized scan is for non-connection purposes, i.e. it won't trigger a wifi connection
+     *    even though it finds some known networks.
+     *
+     * 2. Customized scan result may include access points that is not specified in the channel
+     *    list. An app will need to do frequency filtering if it wants to get pure results for the
+     *    channel list it specified.
+     *
+     * @hide
+     */
+    public boolean startCustomizedScan(ScanSettings requested) {
+        try {
+            mService.startScan(requested, null);
+            return true;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /** @hide */
+    public boolean startCustomizedScan(ScanSettings requested, WorkSource workSource) {
+        try {
+            mService.startScan(requested, workSource);
             return true;
         } catch (RemoteException e) {
             return false;