Merge "Fix postUrl to call loadUrl when url is not a network url."
diff --git a/Android.mk b/Android.mk
index 0865d24..d478a59 100644
--- a/Android.mk
+++ b/Android.mk
@@ -260,6 +260,8 @@
 	media/java/android/media/IAudioService.aidl \
 	media/java/android/media/IAudioFocusDispatcher.aidl \
 	media/java/android/media/IAudioRoutesObserver.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 \
diff --git a/api/current.txt b/api/current.txt
index 7673ff3..a0a4e91 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -543,6 +543,7 @@
     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 = 16843774; // 0x10103fe
     field public static final int fromXDelta = 16843206; // 0x10101c6
     field public static final int fromXScale = 16843202; // 0x10101c2
     field public static final int fromYDelta = 16843208; // 0x10101c8
@@ -960,6 +961,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 = 16843776; // 0x1010400
     field public static final int sharedUserId = 16842763; // 0x101000b
     field public static final int sharedUserLabel = 16843361; // 0x1010261
     field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1142,6 +1144,7 @@
     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 = 16843775; // 0x10103ff
     field public static final int toXDelta = 16843207; // 0x10101c7
     field public static final int toXScale = 16843203; // 0x10101c3
     field public static final int toYDelta = 16843209; // 0x10101c9
@@ -1157,6 +1160,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 = 16843777; // 0x1010401
     field public static final int transitionOrdering = 16843744; // 0x10103e0
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
@@ -1514,6 +1518,7 @@
     field public static final int selectAll = 16908319; // 0x102001f
     field public static final int selectTextMode = 16908333; // 0x102002d
     field public static final int selectedIcon = 16908302; // 0x102000e
+    field public static final int shared_element_name = 16908334; // 0x102002e
     field public static final int startSelectingText = 16908328; // 0x1020028
     field public static final int stopSelectingText = 16908329; // 0x1020029
     field public static final int summary = 16908304; // 0x1020010
@@ -3035,6 +3040,7 @@
     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();
@@ -3130,6 +3136,7 @@
     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);
@@ -3170,6 +3177,7 @@
     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);
@@ -3340,6 +3348,7 @@
   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 makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
@@ -3349,8 +3358,11 @@
     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 {
@@ -6201,6 +6213,7 @@
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
     method public abstract java.io.File getDir(java.lang.String, int);
+    method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
     method public abstract java.io.File[] getExternalCacheDirs();
     method public abstract java.io.File getExternalFilesDir(java.lang.String);
@@ -8012,7 +8025,9 @@
     method public int getDimensionPixelSize(int) throws android.content.res.Resources.NotFoundException;
     method public android.util.DisplayMetrics getDisplayMetrics();
     method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
     method public android.graphics.drawable.Drawable getDrawableForDensity(int, int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawableForDensity(int, int, android.content.res.Resources.Theme);
     method public float getFraction(int, int, int);
     method public int getIdentifier(java.lang.String, java.lang.String, java.lang.String);
     method public int[] getIntArray(int) throws android.content.res.Resources.NotFoundException;
@@ -8056,6 +8071,7 @@
   public final class Resources.Theme {
     method public void applyStyle(int, boolean);
     method public void dump(int, java.lang.String, java.lang.String);
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet, int[], int, int);
@@ -10647,11 +10663,24 @@
     ctor public RotateDrawable();
     method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
+    method public float getFromDegrees();
     method public int getOpacity();
+    method public float getPivotX();
+    method public float getPivotY();
+    method public float getToDegrees();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public boolean isPivotXRelative();
+    method public boolean isPivotYRelative();
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setFromDegrees(float);
+    method public void setPivotX(float);
+    method public void setPivotXRelative(boolean);
+    method public void setPivotY(float);
+    method public void setPivotYRelative(boolean);
+    method public void setToDegrees(float);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
 
@@ -11245,6 +11274,7 @@
     field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_HYPERFOCAL_DISTANCE;
     field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
     field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_SHADING_MAP_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_INPUT_STREAMS;
     field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_OUTPUT_STREAMS;
     field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PARTIAL_RESULT_COUNT;
     field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PIPELINE_MAX_DEPTH;
@@ -18358,7 +18388,7 @@
 
   public abstract class CountDownTimer {
     ctor public CountDownTimer(long, long);
-    method public final void cancel();
+    method public final synchronized void cancel();
     method public abstract void onFinish();
     method public abstract void onTick(long);
     method public final synchronized android.os.CountDownTimer start();
@@ -26662,6 +26692,7 @@
     method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
     method public android.transition.Transition addTarget(int);
     method public android.transition.Transition addTarget(android.view.View);
+    method public boolean canRemoveViews();
     method public abstract void captureEndValues(android.transition.TransitionValues);
     method public abstract void captureStartValues(android.transition.TransitionValues);
     method public android.transition.Transition clone();
@@ -28726,6 +28757,7 @@
     method public int getScrollBarStyle();
     method public final int getScrollX();
     method public final int getScrollY();
+    method public java.lang.String getSharedElementName();
     method public int getSolidColor();
     method protected int getSuggestedMinimumHeight();
     method protected int getSuggestedMinimumWidth();
@@ -28979,6 +29011,7 @@
     method public void setScrollY(int);
     method public void setScrollbarFadingEnabled(boolean);
     method public void setSelected(boolean);
+    method public void setSharedElementName(java.lang.String);
     method public void setSoundEffectsEnabled(boolean);
     method public void setSystemUiVisibility(int);
     method public void setTag(java.lang.Object);
@@ -29365,6 +29398,7 @@
     method protected boolean isChildrenDrawingOrderEnabled();
     method protected boolean isChildrenDrawnWithCacheEnabled();
     method public boolean isMotionEventSplittingEnabled();
+    method public boolean isTransitionGroup();
     method public final void layout(int, int, int, int);
     method protected void measureChild(android.view.View, int, int);
     method protected void measureChildWithMargins(android.view.View, int, int, int, int);
@@ -29410,6 +29444,7 @@
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
     method public void setPersistentDrawingCache(int);
     method protected void setStaticTransformationsEnabled(boolean);
+    method public void setTransitionGroup(boolean);
     method public boolean shouldDelayChildPressedState();
     method public boolean showContextMenuForChild(android.view.View);
     method public android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback);
@@ -29704,7 +29739,6 @@
     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 setTransitionOptions(android.os.Bundle);
     method public void setType(int);
     method public void setUiOptions(int);
     method public void setUiOptions(int, int);
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index bfbae24..242b3ea 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -100,7 +100,7 @@
             try {
                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
             } catch (PackageManager.NameNotFoundException e) {
                 // Nothing we can do much here, just log
                 if (Log.isLoggable(TAG, Log.WARN)) {
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index acc8549..a3222d8 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -129,7 +129,7 @@
             Drawable icon = null;
             try {
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
                 final CharSequence sequence = authContext.getResources().getText(desc.labelId);
                 if (sequence != null) {
                     name = sequence.toString();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 698f06a..a8716bf 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.transition.Scene;
-import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.util.ArrayMap;
 import android.util.SuperNotCalledException;
@@ -771,6 +770,7 @@
 
     private Thread mUiThread;
     final Handler mHandler = new Handler();
+    private ActivityOptions mTransitionActivityOptions;
 
     /** Return the intent that started this activity. */
     public Intent getIntent() {
@@ -3443,38 +3443,16 @@
      *
      * @throws android.content.ActivityNotFoundException
      *
-     * @see #startActivity 
+     * @see #startActivity
      */
     public void startActivityForResult(Intent intent, int requestCode) {
-        final TransitionManager tm = getWindow().getTransitionManager();
-        final Scene currScene = getWindow().getContentScene();
-        final String[] targetSceneNames = currScene != null && tm != null ?
-                tm.getTargetSceneNames(currScene) : null;
-
-        if (targetSceneNames == null || targetSceneNames.length == 0) {
-            startActivityForResult(intent, requestCode, null);
-        } else {
-            // TODO Capture the scene transition args and send along
-            final ActivityOptions opts = ActivityOptions.makeSceneTransitionAnimation(
-                    targetSceneNames, null,
-                    new ActivityOptions.OnSceneTransitionStartedListener() {
-                        @Override public void onSceneTransitionStarted(String destSceneName) {
-                            final Transition t = tm.getNamedTransition(currScene, destSceneName);
-                            // TODO Fill this in to notify the outgoing activity that it should
-                            // treat this as a sync point for the transition - the target
-                            // transition has started.
-                            Log.d(TAG, "Scene transition to scene " + destSceneName +
-                                    " transition " + t);
-                        }
-                    }, mHandler);
-            startActivityForResult(intent, requestCode, opts.toBundle());
-        }
+        startActivityForResult(intent, requestCode, null);
     }
 
     /**
      * Launch an activity for which you would like a result when it finished.
      * When this activity exits, your
-     * onActivityResult() method will be called with the given requestCode. 
+     * onActivityResult() method will be called with the given requestCode.
      * Using a negative requestCode is the same as calling 
      * {@link #startActivity} (the activity is not launched as a sub-activity).
      *
@@ -3487,9 +3465,9 @@
      *
      * <p>As a special case, if you call startActivityForResult() with a requestCode 
      * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
-     * activity, then your window will not be displayed until a result is 
-     * returned back from the started activity.  This is to avoid visible 
-     * flickering when redirecting to another activity. 
+     * activity, then your window will not be displayed until a result is
+     * returned back from the started activity.  This is to avoid visible
+     * flickering when redirecting to another activity.
      *
      * <p>This method throws {@link android.content.ActivityNotFoundException}
      * if there was no Activity found to run the given Intent.
@@ -3503,9 +3481,17 @@
      *
      * @throws android.content.ActivityNotFoundException
      *
-     * @see #startActivity 
+     * @see #startActivity
      */
     public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
+        TransitionManager tm = getContentTransitionManager();
+        if (tm != null && options != null) {
+            ActivityOptions activityOptions = new ActivityOptions(options);
+            if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+                getWindow().startExitTransition(activityOptions);
+                options = activityOptions.toBundle();
+            }
+        }
         if (mParent == null) {
             Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivity(
@@ -5313,7 +5299,7 @@
             mWindow.setUiOptions(info.uiOptions);
         }
         mUiThread = Thread.currentThread();
-        
+
         mMainThread = aThread;
         mInstrumentation = instr;
         mToken = token;
@@ -5335,8 +5321,40 @@
             mWindow.setContainer(mParent.getWindow());
         }
         mWindowManager = mWindow.getWindowManager();
-        mWindow.setTransitionOptions(options);
         mCurrentConfig = config;
+        mTransitionActivityOptions = null;
+        Window.SceneTransitionListener sceneTransitionListener = null;
+        if (options != null) {
+            ActivityOptions activityOptions = new ActivityOptions(options);
+            if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+                mTransitionActivityOptions = activityOptions;
+                sceneTransitionListener = new Window.SceneTransitionListener() {
+                    @Override
+                    public void enterSharedElement(Bundle transitionArgs) {
+                        startSharedElementTransition(transitionArgs);
+                        mTransitionActivityOptions = null;
+                    }
+
+                    @Override
+                    public void nullPendingTransition() {
+                        overridePendingTransition(0, 0);
+                    }
+
+                    @Override
+                    public void convertFromTranslucent() {
+                        Activity.this.convertFromTranslucent();
+                    }
+
+                    @Override
+                    public void convertToTranslucent() {
+                        Activity.this.convertToTranslucent(null);
+                    }
+                };
+
+            }
+        }
+
+        mWindow.setTransitionOptions(mTransitionActivityOptions, sceneTransitionListener);
     }
 
     /** @hide */
@@ -5350,7 +5368,7 @@
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
         mFragments.dispatchActivityCreated();
     }
-    
+
     final void performStart() {
         mFragments.noteStateNotSaved();
         mCalled = false;
@@ -5507,7 +5525,7 @@
                     }
                 }
             }
-    
+
             mStopped = true;
         }
         mResumed = false;
@@ -5522,7 +5540,57 @@
             mLoaderManager.doDestroy();
         }
     }
-    
+
+    /**
+     * 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>
+     *
+     * @return The Bundle passed into Bundle parameter of
+     *         {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)}
+     *         in the calling Activity.
+     */
+    public Bundle getTransitionArgs() {
+        if (mTransitionActivityOptions == null) {
+            return null;
+        }
+        return mTransitionActivityOptions.getSceneTransitionArgs();
+    }
+
+    /**
+     * 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.
+     */
+    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);
+    }
+
     /**
      * @hide
      */
@@ -5530,7 +5598,7 @@
         return mResumed;
     }
 
-    void dispatchActivityResult(String who, int requestCode, 
+    void dispatchActivityResult(String who, int requestCode,
         int resultCode, Intent data) {
         if (false) Log.v(
             TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 582ce3c..3f97c40 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -16,16 +16,21 @@
 
 package android.app;
 
+import android.animation.Animator;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
-import android.text.TextUtils;
+import android.transition.Transition;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.View;
 
+import java.util.ArrayList;
+import java.util.Map;
+
 /**
  * Helper class for building an options Bundle that can be used with
  * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
@@ -95,34 +100,30 @@
     public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
 
     /**
-     * A string array of names for the destination scene. This defines an API in the same
-     * way that intent action or extra names do and should follow a similar convention:
-     * "com.example.scene.FOO"
-     *
-     * @hide
-     */
-    public static final String KEY_DEST_SCENE_NAMES = "android:destSceneNames";
-
-    /**
-     * A string indicating the destination scene name that was chosen by the target.
-     * Used by {@link OnSceneTransitionStartedListener}.
-     * @hide
-     */
-    public static final String KEY_DEST_SCENE_NAME_CHOSEN = "android:destSceneNameChosen";
-
-    /**
-     * Callback for when scene transition is started.
-     * @hide
-     */
-    public static final String KEY_SCENE_TRANSITION_START_LISTENER =
-            "android:sceneTransitionStartListener";
-
-    /**
      * 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.
+     */
+    private static final String KEY_TRANSITION_COMPLETE_LISTENER
+            = "android:transitionCompleteListener";
+
+    /**
+     * For Activity transitions, the called Activity's listener to receive calls
+     * when transitions complete.
+     */
+    private static final String KEY_TRANSITION_TARGET_LISTENER = "android:transitionTargetListener";
+
+    /**
+     * The shared element's texture ID (TODO: not used yet).
+     */
+    private static final String KEY_SHARED_ELEMENT_TEXTURE_ID = "android:sharedElementTextureId";
+
     /** @hide */
     public static final int ANIM_NONE = 0;
     /** @hide */
@@ -145,10 +146,9 @@
     private int mStartY;
     private int mStartWidth;
     private int mStartHeight;
-    private String[] mDestSceneNames;
     private Bundle mTransitionArgs;
     private IRemoteCallback mAnimationStartedListener;
-    private IRemoteCallback mSceneTransitionStartedListener;
+    private IRemoteCallback mTransitionCompleteListener;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -215,24 +215,6 @@
         }
     }
 
-    private void setOnSceneTransitionStartedListener(Handler handler,
-            OnSceneTransitionStartedListener listener) {
-        if (listener != null) {
-            final Handler h = handler;
-            final OnSceneTransitionStartedListener l = listener;
-            mSceneTransitionStartedListener = new IRemoteCallback.Stub() {
-                @Override public void sendResult(final Bundle data) throws RemoteException {
-                    h.post(new Runnable() {
-                        public void run() {
-                            l.onSceneTransitionStarted(data != null ?
-                                    data.getString(KEY_DEST_SCENE_NAME_CHOSEN) : null);
-                        }
-                    });
-                }
-            };
-        }
-    }
-
     /**
      * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
      * to find out when the given animation has started running.
@@ -242,13 +224,10 @@
         void onAnimationStarted();
     }
 
-    /**
-     * Callback for use with {@link ActivityOptions#makeSceneTransitionAnimation}
-     * to find out when a transition is about to begin.
-     * @hide
-     */
-    public interface OnSceneTransitionStartedListener {
-        void onSceneTransitionStarted(String destSceneName);
+    /** @hide */
+    public interface ActivityTransitionTarget {
+        void sharedElementTransitionComplete();
+        void exitTransitionComplete();
     }
 
     /**
@@ -369,18 +348,35 @@
     }
 
     /**
-     * Create an ActivityOptions specifying an animation where an activity window is asked
-     * to perform animations within the window content.
+     * 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.
      *
-     * @hide
+     * 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>
+     *
+     * <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)
      */
-    public static ActivityOptions makeSceneTransitionAnimation(String[] destSceneNames,
-            Bundle args, OnSceneTransitionStartedListener listener, Handler handler) {
+    public static ActivityOptions makeSceneTransitionAnimation(Bundle args) {
         ActivityOptions opts = new ActivityOptions();
         opts.mAnimationType = ANIM_SCENE_TRANSITION;
-        opts.mDestSceneNames = destSceneNames;
         opts.mTransitionArgs = args;
-        opts.setOnSceneTransitionStartedListener(handler, listener);
         return opts;
     }
 
@@ -416,10 +412,9 @@
                 break;
 
             case ANIM_SCENE_TRANSITION:
-                mDestSceneNames = opts.getStringArray(KEY_DEST_SCENE_NAMES);
                 mTransitionArgs = opts.getBundle(KEY_SCENE_TRANSITION_ARGS);
-                mSceneTransitionStartedListener = IRemoteCallback.Stub.asInterface(
-                        opts.getBinder(KEY_SCENE_TRANSITION_START_LISTENER));
+                mTransitionCompleteListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_TRANSITION_COMPLETE_LISTENER));
                 break;
         }
     }
@@ -470,11 +465,6 @@
     }
 
     /** @hide */
-    public String[] getDestSceneNames() {
-        return mDestSceneNames;
-    }
-
-    /** @hide */
     public Bundle getSceneTransitionArgs() {
         return mTransitionArgs;
     }
@@ -485,19 +475,33 @@
     }
 
     /** @hide */
-    public void dispatchSceneTransitionStarted(String destScene) {
-        if (mSceneTransitionStartedListener != null) {
-            Bundle data = null;
-            if (!TextUtils.isEmpty(destScene)) {
-                data = new Bundle();
-                data.putString(KEY_DEST_SCENE_NAME_CHOSEN, destScene);
-            }
+    public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target) {
+        boolean listenerSent = false;
+        if (mTransitionCompleteListener != null) {
+            IRemoteCallback callback = new IRemoteCallback.Stub() {
+                @Override
+                public void sendResult(Bundle data) throws RemoteException {
+                    if (data == null) {
+                        target.exitTransitionComplete();
+                    } else {
+                        // TODO: Use texture id
+                        target.sharedElementTransitionComplete();
+                    }
+                }
+            };
+            Bundle bundle = new Bundle();
+            bundle.putBinder(KEY_TRANSITION_TARGET_LISTENER, callback.asBinder());
             try {
-                mSceneTransitionStartedListener.sendResult(data);
+                mTransitionCompleteListener.sendResult(bundle);
+                listenerSent = true;
             } catch (RemoteException e) {
-                Log.e(TAG, "Caught exception dispatching scene transition start", e);
+                Log.w(TAG, "Couldn't retrieve transition notifications", e);
             }
         }
+        if (!listenerSent) {
+            target.sharedElementTransitionComplete();
+            target.exitTransitionComplete();
+        }
     }
 
     /** @hide */
@@ -508,12 +512,6 @@
             } catch (RemoteException e) {
             }
         }
-        if (mSceneTransitionStartedListener != null) {
-            try {
-                mSceneTransitionStartedListener.sendResult(null);
-            } catch (RemoteException e) {
-            }
-        }
     }
 
     /** @hide */
@@ -545,9 +543,8 @@
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
-                mSceneTransitionStartedListener = null;
+                mTransitionCompleteListener = null;
                 mTransitionArgs = null;
-                mDestSceneNames = null;
                 break;
             case ANIM_SCALE_UP:
                 mAnimationType = otherOptions.mAnimationType;
@@ -562,9 +559,8 @@
                     }
                 }
                 mAnimationStartedListener = null;
-                mSceneTransitionStartedListener = null;
+                mTransitionCompleteListener = null;
                 mTransitionArgs = null;
-                mDestSceneNames = null;
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
@@ -579,20 +575,12 @@
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
-                mSceneTransitionStartedListener = null;
+                mTransitionCompleteListener = null;
                 mTransitionArgs = null;
-                mDestSceneNames = null;
                 break;
             case ANIM_SCENE_TRANSITION:
                 mAnimationType = otherOptions.mAnimationType;
-                if (mSceneTransitionStartedListener != null) {
-                    try {
-                        mSceneTransitionStartedListener.sendResult(null);
-                    } catch (RemoteException e) {
-                    }
-                }
-                mSceneTransitionStartedListener = otherOptions.mSceneTransitionStartedListener;
-                mDestSceneNames = otherOptions.mDestSceneNames;
+                mTransitionCompleteListener = otherOptions.mTransitionCompleteListener;
                 mTransitionArgs = otherOptions.mTransitionArgs;
                 mThumbnail = null;
                 mAnimationStartedListener = null;
@@ -639,10 +627,11 @@
                 break;
             case ANIM_SCENE_TRANSITION:
                 b.putInt(KEY_ANIM_TYPE, mAnimationType);
-                b.putStringArray(KEY_DEST_SCENE_NAMES, mDestSceneNames);
                 b.putBundle(KEY_SCENE_TRANSITION_ARGS, mTransitionArgs);
-                b.putBinder(KEY_SCENE_TRANSITION_START_LISTENER, mSceneTransitionStartedListener
-                        != null ? mSceneTransitionStartedListener.asBinder() : null);
+                if (mTransitionCompleteListener != null) {
+                    b.putBinder(KEY_TRANSITION_COMPLETE_LISTENER,
+                            mTransitionCompleteListener.asBinder());
+                }
                 break;
         }
         return b;
@@ -661,4 +650,123 @@
 
         return null;
     }
+
+    /** @hide */
+    public interface SharedElementSource {
+        int getTextureId();
+    }
+
+    /**
+     * 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);
+    }
+
+    private static class ExitTransitionListener extends IRemoteCallback.Stub
+            implements Transition.TransitionListener, Animator.AnimatorListener {
+        private ArrayList<Animator> mSharedElementAnimators = new ArrayList<Animator>();
+        private boolean mSharedElementNotified;
+        private Transition mExitTransition;
+        private IRemoteCallback mTransitionCompleteCallback;
+        private boolean mExitComplete;
+        private SharedElementSource mSharedElementSource;
+
+        public ExitTransitionListener(Transition transition, SharedElementSource sharedElementSource) {
+            mSharedElementSource = sharedElementSource;
+            mExitTransition = transition;
+            mExitTransition.addListener(this);
+        }
+
+        @Override
+        public void sendResult(Bundle data) throws RemoteException {
+            if (data != null) {
+                mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(
+                        data.getBinder(KEY_TRANSITION_TARGET_LISTENER));
+                notifySharedElement();
+                notifyExit();
+            }
+        }
+
+        @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);
+        }
+
+        @Override
+        public void onTransitionCancel(Transition transition) {
+            mExitComplete = true;
+            notifyExit();
+            mExitTransition.removeListener(this);
+        }
+
+        @Override
+        public void onTransitionPause(Transition transition) {
+        }
+
+        @Override
+        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()
+                    && mTransitionCompleteCallback != null) {
+                mSharedElementNotified = true;
+                try {
+                    Bundle bundle = new Bundle();
+                    bundle.putInt(KEY_SHARED_ELEMENT_TEXTURE_ID, mSharedElementSource.getTextureId());
+                    mTransitionCompleteCallback.sendResult(bundle);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Couldn't notify that the transition ended", e);
+                }
+            }
+        }
+
+        private void notifyExit() {
+            if (mExitComplete && mTransitionCompleteCallback != null) {
+                try {
+                    mTransitionCompleteCallback.sendResult(null);
+                } 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 25cde8c..df4ec78 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.graphics.SurfaceTexture;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -28,6 +29,7 @@
 import android.view.Surface;
 import android.view.TextureView;
 import android.view.TextureView.SurfaceTextureListener;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 
@@ -37,7 +39,6 @@
     private final TextureView mTextureView;
     private IActivityContainer mActivityContainer;
     private Activity mActivity;
-    private boolean mAttached;
     private int mWidth;
     private int mHeight;
     private Surface mSurface;
@@ -85,24 +86,33 @@
                     + e);
         }
 
-        final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
-        if (surfaceTexture != null) {
-            attachToSurface(surfaceTexture);
-        }
+        attachToSurfaceWhenReady();
     }
 
     @Override
     protected void onDetachedFromWindow() {
-        detachFromSurface();
+        if (mActivityContainer != null) {
+            detach();
+            mActivityContainer = null;
+        }
     }
 
     @Override
-    public boolean isAttachedToWindow() {
-        return mAttached;
+    protected void onWindowVisibilityChanged(int visibility) {
+        super.onWindowVisibilityChanged(visibility);
+        if (visibility == View.VISIBLE) {
+            attachToSurfaceWhenReady();
+        } else {
+            detach();
+        }
+    }
+
+    public boolean isAttachedToDisplay() {
+        return mSurface != null;
     }
 
     public void startActivity(Intent intent) {
-        if (mActivityContainer != null && mAttached) {
+        if (mSurface != null) {
             try {
                 mActivityContainer.startActivity(intent);
             } catch (RemoteException e) {
@@ -111,40 +121,59 @@
         }
     }
 
-    /** Call when both mActivityContainer and mTextureView's SurfaceTexture are not null */
-    private void attachToSurface(SurfaceTexture surfaceTexture) {
+    public void startActivity(IntentSender intentSender) {
+        if (mSurface != null) {
+            try {
+                mActivityContainer.startActivityIntentSender(intentSender.getTarget());
+            } catch (RemoteException e) {
+                throw new IllegalStateException(
+                        "ActivityView: Unable to startActivity from IntentSender. " + e);
+            }
+        }
+    }
+
+    public void startActivity(PendingIntent pendingIntent) {
+        if (mSurface != null) {
+            try {
+                mActivityContainer.startActivityIntentSender(pendingIntent.getTarget());
+            } catch (RemoteException e) {
+                throw new IllegalStateException(
+                        "ActivityView: Unable to startActivity from PendingIntent. " + e);
+            }
+        }
+    }
+
+    private void attachToSurfaceWhenReady() {
+        final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
+        if (mActivityContainer == null || surfaceTexture == null || mSurface != null) {
+            // Either not ready to attach, or already attached.
+            return;
+        }
+
         WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
         DisplayMetrics metrics = new DisplayMetrics();
         wm.getDefaultDisplay().getMetrics(metrics);
 
         mSurface = new Surface(surfaceTexture);
         try {
-            mActivityContainer.attachToSurface(mSurface, mWidth, mHeight,
-                    metrics.densityDpi);
+            mActivityContainer.attachToSurface(mSurface, mWidth, mHeight, metrics.densityDpi);
         } catch (RemoteException e) {
-            mActivityContainer = null;
             mSurface.release();
             mSurface = null;
-            mAttached = false;
             throw new IllegalStateException(
                     "ActivityView: Unable to create ActivityContainer. " + e);
         }
-        mAttached = true;
     }
 
-    private void detachFromSurface() {
-        if (mActivityContainer != null) {
+    private void detach() {
+        if (mSurface != null) {
             try {
                 mActivityContainer.detachFromDisplay();
             } catch (RemoteException e) {
             }
-            mActivityContainer = null;
-        }
-        if (mSurface != null) {
             mSurface.release();
             mSurface = null;
         }
-        mAttached = false;
     }
 
     private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
@@ -154,7 +183,7 @@
             mWidth = width;
             mHeight = height;
             if (mActivityContainer != null) {
-                attachToSurface(surfaceTexture);
+                attachToSurfaceWhenReady();
             }
         }
 
@@ -167,7 +196,7 @@
         @Override
         public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
             Log.d(TAG, "onSurfaceTextureDestroyed");
-            detachFromSurface();
+            detach();
             return true;
         }
 
diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
index df1cf91..abd296a 100644
--- a/core/java/android/app/IActivityContainer.aidl
+++ b/core/java/android/app/IActivityContainer.aidl
@@ -18,6 +18,7 @@
 
 import android.app.IActivityContainerCallback;
 import android.content.Intent;
+import android.content.IIntentSender;
 import android.os.IBinder;
 import android.view.Surface;
 
@@ -27,5 +28,6 @@
     void attachToSurface(in Surface surface, int width, int height, int density);
     void detachFromDisplay();
     int startActivity(in Intent intent);
+    int startActivityIntentSender(in IIntentSender intentSender);
     int getDisplayId();
 }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d04e9db..af1810b 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -188,8 +188,7 @@
                 mSearchView.findViewById(com.android.internal.R.id.search_src_text);
         mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon);
         mSearchPlate = mSearchView.findViewById(com.android.internal.R.id.search_plate);
-        mWorkingSpinner = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.search_spinner);
+        mWorkingSpinner = getContext().getDrawable(com.android.internal.R.drawable.search_spinner);
         // TODO: Restore the spinner for slow suggestion lookups
         // mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
         //        null, null, mWorkingSpinner, null);
@@ -458,7 +457,7 @@
 
         // optionally show one or the other.
         if (mSearchable.useBadgeIcon()) {
-            icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
+            icon = mActivityContext.getDrawable(mSearchable.getIconId());
             visibility = View.VISIBLE;
             if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
         } else if (mSearchable.useBadgeLabel()) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ac08d9b..9f90de0 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -376,6 +376,19 @@
         return getResources().getString(resId, formatArgs);
     }
 
+    /**
+     * Return a drawable object associated with a particular resource ID and
+     * styled for the current theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt
+     *           tool. This integer encodes the package, type, and resource
+     *           entry. The value 0 is an invalid identifier.
+     * @return Drawable An object that can be used to draw this resource.
+     */
+    public final Drawable getDrawable(int id) {
+        return getResources().getDrawable(id, getTheme());
+    }
+
      /**
      * Set the base theme for this context.  Note that this should be called
      * before any views are instantiated in the Context (for example before
diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java
index 350f35e..093fb08 100644
--- a/core/java/android/content/SyncActivityTooManyDeletes.java
+++ b/core/java/android/content/SyncActivityTooManyDeletes.java
@@ -95,7 +95,7 @@
 //                try {
 //                    final Context authContext = createPackageContext(desc.packageName, 0);
 //                    ImageView imageView = new ImageView(this);
-//                    imageView.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
+//                    imageView.setImageDrawable(authContext.getDrawable(desc.iconId));
 //                    ll.addView(imageView, lp);
 //                } catch (PackageManager.NameNotFoundException e) {
 //                }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 185bfd8..aa96f0e 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -686,12 +686,27 @@
      * @param id The desired resource identifier, as generated by the aapt
      *           tool. This integer encodes the package, type, and resource
      *           entry. The value 0 is an invalid identifier.
-     *
-     * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
-     * 
      * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *         not exist.
      */
     public Drawable getDrawable(int id) throws NotFoundException {
+        return getDrawable(id, null);
+    }
+
+    /**
+     * Return a drawable object associated with a particular resource ID and
+     * styled for the specified theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt
+     *           tool. This integer encodes the package, type, and resource
+     *           entry. The value 0 is an invalid identifier.
+     * @param theme The theme used to style the drawable attributes.
+     * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *         not exist.
+     */
+    public Drawable getDrawable(int id, Theme theme) throws NotFoundException {
         TypedValue value;
         synchronized (mAccessLock) {
             value = mTmpValue;
@@ -702,7 +717,7 @@
             }
             getValue(id, value, true);
         }
-        Drawable res = loadDrawable(value, id);
+        final Drawable res = loadDrawable(value, id, theme);
         synchronized (mAccessLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
@@ -720,17 +735,36 @@
      * depending on the underlying resource -- for example, a solid color, PNG
      * image, scalable image, etc. The Drawable API hides these implementation
      * details.
-     * 
+     *
      * @param id The desired resource identifier, as generated by the aapt tool.
      *            This integer encodes the package, type, and resource entry.
      *            The value 0 is an invalid identifier.
      * @param density the desired screen density indicated by the resource as
      *            found in {@link DisplayMetrics}.
+     * @return Drawable An object that can be used to draw this resource.
      * @throws NotFoundException Throws NotFoundException if the given ID does
      *             not exist.
-     * @return Drawable An object that can be used to draw this resource.
+     * @see #getDrawableForDensity(int, int, Theme)
      */
     public Drawable getDrawableForDensity(int id, int density) throws NotFoundException {
+        return getDrawableForDensity(id, density, null);
+    }
+
+    /**
+     * Return a drawable object associated with a particular resource ID for the
+     * given screen density in DPI and styled for the specified theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt tool.
+     *            This integer encodes the package, type, and resource entry.
+     *            The value 0 is an invalid identifier.
+     * @param density The desired screen density indicated by the resource as
+     *            found in {@link DisplayMetrics}.
+     * @param theme The theme used to style the drawable attributes.
+     * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *             not exist.
+     */
+    public Drawable getDrawableForDensity(int id, int density, Theme theme) {
         TypedValue value;
         synchronized (mAccessLock) {
             value = mTmpValue;
@@ -757,7 +791,7 @@
             }
         }
 
-        Drawable res = loadDrawable(value, id);
+        final Drawable res = loadDrawable(value, id, theme);
         synchronized (mAccessLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
@@ -1251,8 +1285,9 @@
          * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
          */
         public TypedArray obtainStyledAttributes(int[] attrs) {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
+            array.mTheme = this;
             array.mRsrcs = attrs;
             AssetManager.applyStyle(mTheme, 0, 0, 0, attrs,
                     array.mData, array.mIndices);
@@ -1279,10 +1314,10 @@
          * @see #obtainStyledAttributes(int[])
          * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
          */
-        public TypedArray obtainStyledAttributes(int resid, int[] attrs)
-                throws NotFoundException {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+        public TypedArray obtainStyledAttributes(int resid, int[] attrs) throws NotFoundException {
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
+            array.mTheme = this;
             array.mRsrcs = attrs;
 
             AssetManager.applyStyle(mTheme, 0, resid, 0, attrs,
@@ -1366,19 +1401,18 @@
          */
         public TypedArray obtainStyledAttributes(AttributeSet set,
                 int[] attrs, int defStyleAttr, int defStyleRes) {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
 
             // XXX note that for now we only work with compiled XML files.
             // To support generic XML files we will need to manually parse
             // out the attributes from the XML file (applying type information
             // contained in the resources and such).
-            XmlBlock.Parser parser = (XmlBlock.Parser)set;
-            AssetManager.applyStyle(
-                mTheme, defStyleAttr, defStyleRes,
-                parser != null ? parser.mParseState : 0, attrs,
-                        array.mData, array.mIndices);
+            final XmlBlock.Parser parser = (XmlBlock.Parser)set;
+            AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
+                    parser != null ? parser.mParseState : 0, attrs, array.mData, array.mIndices);
 
+            array.mTheme = this;
             array.mRsrcs = attrs;
             array.mXml = parser;
 
@@ -1444,6 +1478,21 @@
         }
 
         /**
+         * Return a drawable object associated with a particular resource ID
+         * and styled for the Theme.
+         *
+         * @param id The desired resource identifier, as generated by the aapt
+         *           tool. This integer encodes the package, type, and resource
+         *           entry. The value 0 is an invalid identifier.
+         * @return Drawable An object that can be used to draw this resource.
+         * @throws NotFoundException Throws NotFoundException if the given ID
+         *         does not exist.
+         */
+        public Drawable getDrawable(int id) throws NotFoundException {
+            return Resources.this.getDrawable(id, this);
+        }
+
+        /**
          * Print contents of this theme out to the log.  For debugging only.
          * 
          * @param priority The log priority to use.
@@ -1453,7 +1502,8 @@
         public void dump(int priority, String tag, String prefix) {
             AssetManager.dumpTheme(mTheme, priority, tag, prefix);
         }
-        
+
+        @Override
         protected void finalize() throws Throwable {
             super.finalize();
             mAssets.releaseTheme(mTheme);
@@ -1464,6 +1514,7 @@
             mTheme = mAssets.createTheme();
         }
 
+        @SuppressWarnings("hiding")
         private final AssetManager mAssets;
         private final long mTheme;
     }
@@ -2028,14 +2079,14 @@
         return true;
     }
 
-    /*package*/ Drawable loadDrawable(TypedValue value, int id)
-            throws NotFoundException {
-
+    /*package*/ Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
         if (TRACE_FOR_PRELOAD) {
             // Log only framework resources
             if ((id >>> 24) == 0x1) {
                 final String name = getResourceName(id);
-                if (name != null) android.util.Log.d("PreloadDrawable", name);
+                if (name != null) {
+                    Log.d("PreloadDrawable", name);
+                }
             }
         }
 
@@ -2240,12 +2291,12 @@
                     "Resource is not a ColorStateList (color or path): " + value);
         }
         
-        String file = value.string.toString();
+        final String file = value.string.toString();
 
         if (file.endsWith(".xml")) {
             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, file);
             try {
-                XmlResourceParser rp = loadXmlResourceParser(
+                final XmlResourceParser rp = loadXmlResourceParser(
                         file, id, value.assetCookie, "colorstatelist"); 
                 csl = ColorStateList.createFromXml(this, rp);
                 rp.close();
@@ -2372,7 +2423,6 @@
         synchronized (mAccessLock) {
             final TypedArray cached = mCachedStyledAttributes;
             if (cached == null || cached.mData.length < attrs.mData.length) {
-                attrs.mXml = null;
                 mCachedStyledAttributes = attrs;
             }
         }
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 87d65a5..4858d08 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -45,7 +45,8 @@
     /*package*/ int[] mIndices;
     /*package*/ int mLength;
     /*package*/ TypedValue mValue = new TypedValue();
-   
+    /*package*/ Resources.Theme mTheme;
+
     /**
      * Return the number of values in this array.
      */
@@ -600,7 +601,7 @@
                                    + " cookie=" + value.assetCookie);
                 System.out.println("******************************************************************");
             }
-            return mResources.loadDrawable(value, value.resourceId);
+            return mResources.loadDrawable(value, value.resourceId, mTheme);
         }
         return null;
     }
@@ -690,6 +691,10 @@
      */
     public void recycle() {
         mResources.recycleCachedStyledAttributes(this);
+
+        mXml = null;
+        mRsrcs = null;
+        mTheme = null;
     }
 
     private boolean getValueAt(int index, TypedValue outValue) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 8048b24..913b273 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -255,11 +255,18 @@
             new Key<byte[]>("android.control.awbAvailableModes", byte[].class);
 
     /**
-     * <p>For AE, AWB, and AF, how many individual
-     * regions can be listed for metering?</p>
+     * <p>List of the maximum number of regions that can be used for metering in
+     * auto-exposure (AE), auto-white balance (AWB), and auto-focus (AF);
+     * this corresponds to the the maximum number of elements in
+     * {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}, {@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions},
+     * and {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_REGIONS
+     * @see CaptureRequest#CONTROL_AF_REGIONS
+     * @see CaptureRequest#CONTROL_AWB_REGIONS
      */
-    public static final Key<Integer> CONTROL_MAX_REGIONS =
-            new Key<Integer>("android.control.maxRegions", int.class);
+    public static final Key<int[]> CONTROL_MAX_REGIONS =
+            new Key<int[]>("android.control.maxRegions", int[].class);
 
     /**
      * <p>Whether this camera device has a
@@ -391,16 +398,44 @@
             new Key<Byte>("android.quirks.usePartialResult", byte.class);
 
     /**
-     * <p>How many output streams can be allocated at
-     * the same time for each type of stream</p>
-     * <p>Video snapshot with preview callbacks requires 3
-     * processed streams (preview, record, app callbacks) and
-     * one JPEG stream (snapshot)</p>
+     * <p>The maximum numbers of different types of output streams
+     * that can be configured and used simultaneously by a camera device.</p>
+     * <p>This is a 3 element tuple that contains the max number of output simultaneous
+     * streams for raw sensor, processed (and uncompressed), and JPEG formats respectively.
+     * For example, if max raw sensor format output stream number is 1, max YUV streams
+     * number is 3, and max JPEG stream number is 2, then this tuple should be <code>(1, 3, 2)</code>.</p>
+     * <p>This lists the upper bound of the number of output streams supported by
+     * the camera device. Using more streams simultaneously may require more hardware and
+     * CPU resources that will consume more power. The image format for a output stream can
+     * be any supported format provided by {@link CameraCharacteristics#SCALER_AVAILABLE_FORMATS android.scaler.availableFormats}. The formats
+     * defined in {@link CameraCharacteristics#SCALER_AVAILABLE_FORMATS android.scaler.availableFormats} can be catergorized into the 3 stream types
+     * as below:</p>
+     * <ul>
+     * <li>JPEG-compressed format: BLOB.</li>
+     * <li>Raw formats: RAW_SENSOR and RAW_OPAQUE.</li>
+     * <li>processed, uncompressed formats: YCbCr_420_888, YCrCb_420_SP, YV12.</li>
+     * </ul>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_FORMATS
      */
     public static final Key<int[]> REQUEST_MAX_NUM_OUTPUT_STREAMS =
             new Key<int[]>("android.request.maxNumOutputStreams", int[].class);
 
     /**
+     * <p>The maximum numbers of any type of input streams
+     * that can be configured and used simultaneously by a camera device.</p>
+     * <p>When set to 0, it means no input stream is supported.</p>
+     * <p>The image format for a input stream can be any supported format provided
+     * by android.scaler.availableInputFormats. When using an input stream, there must be
+     * at least one output stream configured to to receive the reprocessed images.</p>
+     * <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
+     * stream image format will be RAW_OPAQUE, the associated output stream image format
+     * should be JPEG.</p>
+     */
+    public static final Key<Integer> REQUEST_MAX_NUM_INPUT_STREAMS =
+            new Key<Integer>("android.request.maxNumInputStreams", int.class);
+
+    /**
      * <p>Specifies the number of maximum pipeline stages a frame
      * has to go through from when it's exposed to when it's available
      * to the framework.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 0988c62..1327ba9 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -510,9 +510,9 @@
 
     /**
      * <p>List of areas to use for
-     * metering</p>
+     * metering.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -524,7 +524,7 @@
      * 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
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -582,9 +582,9 @@
 
     /**
      * <p>List of areas to use for focus
-     * estimation</p>
+     * estimation.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -596,7 +596,7 @@
      * 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
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -668,10 +668,10 @@
 
     /**
      * <p>List of areas to use for illuminant
-     * estimation</p>
+     * estimation.</p>
      * <p>Only used in AUTO mode.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -683,7 +683,7 @@
      * 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
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 1f65c19..46d95b1 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -212,9 +212,9 @@
 
     /**
      * <p>List of areas to use for
-     * metering</p>
+     * metering.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -226,7 +226,7 @@
      * 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
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -405,9 +405,9 @@
 
     /**
      * <p>List of areas to use for focus
-     * estimation</p>
+     * estimation.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -419,7 +419,7 @@
      * 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
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -794,10 +794,10 @@
 
     /**
      * <p>List of areas to use for illuminant
-     * estimation</p>
+     * estimation.</p>
      * <p>Only used in AUTO mode.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -809,7 +809,7 @@
      * 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
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 6ac126e..3a35cb9 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -800,6 +800,8 @@
      * Ensure that a network route exists to deliver traffic to the specified
      * host via the specified network interface. An attempt to add a route that
      * already exists is ignored, but treated as successful.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
      * @param networkType the type of the network over which traffic to the specified
      * host is to be routed
      * @param hostAddress the IP address of the host to which the route is desired
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index d9c35c0..3c3d8ec 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -306,18 +306,18 @@
                     if (VDBG) {
                         Slog.d(TAG, "TelephonyMgr.DataConnectionStateChanged");
                         if (mNetworkInfo != null) {
-                            Slog.d(TAG, "NetworkInfo = " + mNetworkInfo.toString());
-                            Slog.d(TAG, "subType = " + String.valueOf(mNetworkInfo.getSubtype()));
+                            Slog.d(TAG, "NetworkInfo = " + mNetworkInfo);
+                            Slog.d(TAG, "subType = " + mNetworkInfo.getSubtype());
                             Slog.d(TAG, "subType = " + mNetworkInfo.getSubtypeName());
                         }
                         if (mLinkProperties != null) {
-                            Slog.d(TAG, "LinkProperties = " + mLinkProperties.toString());
+                            Slog.d(TAG, "LinkProperties = " + mLinkProperties);
                         } else {
                             Slog.d(TAG, "LinkProperties = " );
                         }
 
                         if (mLinkCapabilities != null) {
-                            Slog.d(TAG, "LinkCapabilities = " + mLinkCapabilities.toString());
+                            Slog.d(TAG, "LinkCapabilities = " + mLinkCapabilities);
                         } else {
                             Slog.d(TAG, "LinkCapabilities = " );
                         }
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index 5275bc0..b65eac7 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -169,7 +169,7 @@
      * @param dialogIconRes The icon, as a resource ID.
      */
     public void setDialogIcon(int dialogIconRes) {
-        mDialogIcon = getContext().getResources().getDrawable(dialogIconRes);
+        mDialogIcon = getContext().getDrawable(dialogIconRes);
     }
     
     /**
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 76fccc7..144c909 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -561,7 +561,7 @@
         if (imageView != null) {
             if (mIconResId != 0 || mIcon != null) {
                 if (mIcon == null) {
-                    mIcon = getContext().getResources().getDrawable(mIconResId);
+                    mIcon = getContext().getDrawable(mIconResId);
                 }
                 if (mIcon != null) {
                     imageView.setImageDrawable(mIcon);
@@ -694,7 +694,7 @@
      */
     public void setIcon(int iconResId) {
         mIconResId = iconResId;
-        setIcon(mContext.getResources().getDrawable(iconResId));
+        setIcon(mContext.getDrawable(iconResId));
     }
 
     /**
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 74b9463..3d6f8e6 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -145,7 +145,7 @@
             }
         } else {
             try {
-                drawable = mContext.getResources().getDrawable(mResourceId);
+                drawable = mContext.getDrawable(mResourceId);
                 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                         drawable.getIntrinsicHeight());
             } catch (Exception e) {
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index da9ba5a..fd3f9b3 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -552,7 +552,8 @@
         return false;
     }
 
-    private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
+    /** @hide */
+    public static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
         ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
         if (runningAnimators == null) {
             runningAnimators = new ArrayMap<Animator, AnimationInfo>();
@@ -1077,6 +1078,9 @@
         if (view == null) {
             return;
         }
+        if (!isValidTarget(view, view.getId())) {
+            return;
+        }
         boolean isListViewItem = false;
         if (view.getParent() instanceof ListView) {
             isListViewItem = true;
@@ -1467,6 +1471,10 @@
         mCanRemoveViews = canRemoveViews;
     }
 
+    public boolean canRemoveViews() {
+        return mCanRemoveViews;
+    }
+
     @Override
     public String toString() {
         return toString("");
@@ -1629,9 +1637,10 @@
      * animation should be canceled or a new animation noop'd. The structure holds
      * information about the state that an animation is going to, to be compared to
      * end state of a new animation.
+     * @hide
      */
-    private static class AnimationInfo {
-        View view;
+    public static class AnimationInfo {
+        public View view;
         String name;
         TransitionValues values;
 
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index bb7ed41..063a08d 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -140,7 +140,7 @@
         if ((resourceId & 0xff000000) == 0x01000000) {
             icon.mSystemIconResourceId = resourceId;
         } else {
-            icon.loadResource(context.getResources(), resourceId);
+            icon.loadResource(context, context.getResources(), resourceId);
         }
         return icon;
     }
@@ -198,7 +198,7 @@
         }
 
         PointerIcon icon = new PointerIcon(STYLE_CUSTOM);
-        icon.loadResource(resources, resourceId);
+        icon.loadResource(null, resources, resourceId);
         return icon;
     }
 
@@ -224,7 +224,7 @@
 
         PointerIcon result = new PointerIcon(mStyle);
         result.mSystemIconResourceId = mSystemIconResourceId;
-        result.loadResource(context.getResources(), mSystemIconResourceId);
+        result.loadResource(context, context.getResources(), mSystemIconResourceId);
         return result;
     }
 
@@ -373,7 +373,7 @@
         return true;
     }
 
-    private void loadResource(Resources resources, int resourceId) {
+    private void loadResource(Context context, Resources resources, int resourceId) {
         XmlResourceParser parser = resources.getXml(resourceId);
         final int bitmapRes;
         final float hotSpotX;
@@ -397,7 +397,12 @@
             throw new IllegalArgumentException("<pointer-icon> is missing bitmap attribute.");
         }
 
-        Drawable drawable = resources.getDrawable(bitmapRes);
+        Drawable drawable;
+        if (context == null) {
+            drawable = resources.getDrawable(bitmapRes);
+        } else {
+            drawable = context.getDrawable(bitmapRes);
+        }
         if (!(drawable instanceof BitmapDrawable)) {
             throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
                     + "refer to a bitmap drawable.");
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 55dcbb2..97a1f21 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -177,13 +177,13 @@
      * Equivalent to calling hide().
      * Updates the value set during Surface creation (see {@link #HIDDEN}).
      */
-    public static final int SURFACE_HIDDEN = 0x01;
+    private static final int SURFACE_HIDDEN = 0x01;
 
     /**
      * Surface flag: composite without blending when possible.
      * Updates the value set during Surface creation (see {@link #OPAQUE}).
      */
-    public static final int SURFACE_OPAQUE = 0x02;
+    private static final int SURFACE_OPAQUE = 0x02;
 
 
     /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
@@ -191,13 +191,13 @@
 
     /**
      * Built-in physical display id: Main display.
-     * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+     * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
      */
     public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
 
     /**
      * Built-in physical display id: Attached HDMI display.
-     * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+     * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
      */
     public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
 
@@ -369,18 +369,6 @@
         nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
     }
 
-    /**
-     * Sets and clears flags, such as {@link #SURFACE_HIDDEN}.  The new value will be:
-     * <p>
-     *   <code>newFlags = (oldFlags & ~mask) | (flags & mask)</code>
-     * <p>
-     * Note this does not take the same set of flags as the constructor.
-     */
-    public void setFlags(int flags, int mask) {
-        checkNotReleased();
-        nativeSetFlags(mNativeObject, flags, mask);
-    }
-
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
         if (crop != null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 239eda4..518908f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -665,6 +665,7 @@
  * @attr ref android.R.styleable#View_scrollbarTrackVertical
  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
+ * @attr ref android.R.styleable#View_sharedElementName
  * @attr ref android.R.styleable#View_soundEffectsEnabled
  * @attr ref android.R.styleable#View_tag
  * @attr ref android.R.styleable#View_textAlignment
@@ -2325,7 +2326,18 @@
 
     /* End of masks for mPrivateFlags2 */
 
-    /* Masks for mPrivateFlags3 */
+    /**
+     * Masks for mPrivateFlags3, as generated by dumpFlags():
+     *
+     * |-------|-------|-------|-------|
+     *                                 1 PFLAG3_VIEW_IS_ANIMATING_TRANSFORM
+     *                                1  PFLAG3_VIEW_IS_ANIMATING_ALPHA
+     *                               1   PFLAG3_IS_LAID_OUT
+     *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
+     *                             1     PFLAG3_CALLED_SUPER
+     *                            1      PFLAG3_PROJECT_BACKGROUND
+     * |-------|-------|-------|-------|
+     */
 
     /**
      * Flag indicating that view has a transform animation set on it. This is used to track whether
@@ -2359,6 +2371,11 @@
      */
     static final int PFLAG3_CALLED_SUPER = 0x10;
 
+    /**
+     * Flag indicating that the background of this view will be drawn into a
+     * display list and projected onto the closest parent projection surface.
+     */
+    static final int PFLAG3_PROJECT_BACKGROUND = 0x20;
 
     /* End of masks for mPrivateFlags3 */
 
@@ -3225,6 +3242,15 @@
     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
     private Drawable mBackground;
 
+    /**
+     * Display list used for backgrounds.
+     * <p>
+     * When non-null and valid, this is expected to contain an up-to-date copy
+     * of the background drawable. It is cleared on temporary detach and reset
+     * on cleanup.
+     */
+    private DisplayList mBackgroundDisplayList;
+
     private int mBackgroundResource;
     private boolean mBackgroundSizeChanged;
 
@@ -3503,6 +3529,13 @@
     private Bitmap mDrawingCache;
     private Bitmap mUnscaledDrawingCache;
 
+    /**
+     * Display list used for the View content.
+     * <p>
+     * When non-null and valid, this is expected to contain an up-to-date copy
+     * of the View content. It is cleared on temporary detach and reset on
+     * cleanup.
+     */
     DisplayList mDisplayList;
 
     /**
@@ -4006,6 +4039,9 @@
                 case R.styleable.View_accessibilityLiveRegion:
                     setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
                     break;
+                case R.styleable.View_sharedElementName:
+                    setSharedElementName(a.getString(attr));
+                    break;
             }
         }
 
@@ -13688,12 +13724,20 @@
         if (mDisplayList != null) {
             mDisplayList.clear();
         }
+
+        if (mBackgroundDisplayList != null) {
+            mBackgroundDisplayList.clear();
+        }
     }
 
     private void resetDisplayList() {
         if (mDisplayList != null) {
             mDisplayList.reset();
         }
+
+        if (mBackgroundDisplayList != null) {
+            mBackgroundDisplayList.reset();
+        }
     }
 
     /**
@@ -14721,24 +14765,7 @@
         int saveCount;
 
         if (!dirtyOpaque) {
-            final Drawable background = mBackground;
-            if (background != null) {
-                final int scrollX = mScrollX;
-                final int scrollY = mScrollY;
-
-                if (mBackgroundSizeChanged) {
-                    background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
-                    mBackgroundSizeChanged = false;
-                }
-
-                if ((scrollX | scrollY) == 0) {
-                    background.draw(canvas);
-                } else {
-                    canvas.translate(scrollX, scrollY);
-                    background.draw(canvas);
-                    canvas.translate(-scrollX, -scrollY);
-                }
-            }
+            drawBackground(canvas);
         }
 
         // skip step 2 & 5 if possible (common case)
@@ -14905,6 +14932,93 @@
     }
 
     /**
+     * Draws the background onto the specified canvas.
+     *
+     * @param canvas Canvas on which to draw the background
+     */
+    private void drawBackground(Canvas canvas) {
+        final Drawable background = mBackground;
+        if (background == null) {
+            return;
+        }
+
+        if (mBackgroundSizeChanged) {
+            // We should see the background invalidate itself, but just to be
+            // careful we're going to clear the display list and force redraw.
+            if (mBackgroundDisplayList != null) {
+                mBackgroundDisplayList.clear();
+            }
+
+            background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
+            mBackgroundSizeChanged = false;
+        }
+
+
+        // Attempt to use a display list if requested.
+        if (canvas != null && canvas.isHardwareAccelerated()) {
+            mBackgroundDisplayList = getDrawableDisplayList(background, mBackgroundDisplayList);
+
+            final DisplayList displayList = mBackgroundDisplayList;
+            if (displayList != null && displayList.isValid()) {
+                setBackgroundDisplayListProperties(displayList);
+                ((HardwareCanvas) canvas).drawDisplayList(displayList);
+                return;
+            }
+        }
+
+        final int scrollX = mScrollX;
+        final int scrollY = mScrollY;
+        if ((scrollX | scrollY) == 0) {
+            background.draw(canvas);
+        } else {
+            canvas.translate(scrollX, scrollY);
+            background.draw(canvas);
+            canvas.translate(-scrollX, -scrollY);
+        }
+    }
+
+    /**
+     * Set up background drawable display list properties.
+     *
+     * @param displayList Valid display list for the background drawable
+     */
+    private void setBackgroundDisplayListProperties(DisplayList displayList) {
+        displayList.setProjectBackwards((mPrivateFlags3 & PFLAG3_PROJECT_BACKGROUND) != 0);
+        displayList.setTranslationX(mScrollX);
+        displayList.setTranslationY(mScrollY);
+    }
+
+    /**
+     * Creates a new display list or updates the existing display list for the
+     * specified Drawable.
+     *
+     * @param drawable Drawable for which to create a display list
+     * @param displayList Existing display list, or {@code null}
+     * @return A valid display list for the specified drawable
+     */
+    private static DisplayList getDrawableDisplayList(Drawable drawable, DisplayList displayList) {
+        if (displayList != null && displayList.isValid()) {
+            return displayList;
+        }
+
+        if (displayList == null) {
+            displayList = DisplayList.create(drawable.getClass().getName());
+        }
+
+        final Rect bounds = drawable.getBounds();
+        final int width = bounds.width();
+        final int height = bounds.height();
+        final HardwareCanvas canvas = displayList.start(width, height);
+        drawable.draw(canvas);
+        displayList.end();
+
+        // Set up drawable properties that are view-independent.
+        displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        displayList.setClipToBounds(false);
+        return displayList;
+    }
+
+    /**
      * Returns the overlay for this view, creating it if it does not yet exist.
      * Adding drawables to the overlay will cause them to be displayed whenever
      * the view itself is redrawn. Objects in the overlay should be actively
@@ -15245,14 +15359,22 @@
      *
      * @param drawable the drawable to invalidate
      */
+    @Override
     public void invalidateDrawable(Drawable drawable) {
         if (verifyDrawable(drawable)) {
-            final Rect dirty = drawable.getBounds();
-            final int scrollX = mScrollX;
-            final int scrollY = mScrollY;
+            if (drawable == mBackground && mBackgroundDisplayList != null) {
+                // If we're using a background display list, we only need to
+                // invalidate the display list and notify the parent to redraw.
+                mBackgroundDisplayList.clear();
+                invalidateViewProperty(true, false);
+            } else {
+                final Rect dirty = drawable.getBounds();
+                final int scrollX = mScrollX;
+                final int scrollY = mScrollY;
 
-            invalidate(dirty.left + scrollX, dirty.top + scrollY,
-                    dirty.right + scrollX, dirty.bottom + scrollY);
+                invalidate(dirty.left + scrollX, dirty.top + scrollY,
+                        dirty.right + scrollX, dirty.bottom + scrollY);
+            }
         }
     }
 
@@ -15399,7 +15521,7 @@
      * @see Drawable#setState(int[])
      */
     protected void drawableStateChanged() {
-        Drawable d = mBackground;
+        final Drawable d = mBackground;
         if (d != null && d.isStateful()) {
             d.setState(getDrawableState());
         }
@@ -15584,7 +15706,7 @@
 
         Drawable d= null;
         if (resid != 0) {
-            d = mResources.getDrawable(resid);
+            d = mContext.getDrawable(resid);
         }
         setBackground(d);
 
@@ -18754,6 +18876,35 @@
     }
 
     /**
+     * Specifies that the shared name of the View to be shared with another Activity.
+     * When transitioning between Activities, the name links a UI element in the starting
+     * Activity to UI element in the called Activity. Names should be unique in the
+     * View hierarchy.
+     *
+     * @param sharedElementName The cross-Activity View identifier. The called Activity will use
+     *                 the name to match the location with a View in its layout.
+     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
+     */
+    public void setSharedElementName(String sharedElementName) {
+        setTagInternal(com.android.internal.R.id.shared_element_name, sharedElementName);
+    }
+
+    /**
+     * Returns the shared name of the View to be shared with another Activity.
+     * When transitioning between Activities, the name links a UI element in the starting
+     * Activity to UI element in the called Activity. Names should be unique in the
+     * View hierarchy.
+     *
+     * <p>This returns null if the View is not a shared element or the name if it is.</p>
+     *
+     * @return The name used for this View for cross-Activity transitions or null if
+     * this View has not been identified as shared.
+     */
+    public String getSharedElementName() {
+        return (String) getTag(com.android.internal.R.id.shared_element_name);
+    }
+
+    /**
      * Interface definition for a callback to be invoked when a hardware key event is
      * dispatched to this view. The callback will be invoked before the key event is
      * given to the view. This is only useful for hardware keyboards; a software input
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b91091f..73b108f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -360,6 +360,10 @@
      */
     static final int FLAG_ISOLATED_Z_VOLUME = 0x1000000;
 
+    static final int FLAG_IS_TRANSITION_GROUP = 0x2000000;
+
+    static final int FLAG_IS_TRANSITION_GROUP_SET = 0x4000000;
+
     /**
      * Indicates which types of drawing caches are to be kept in memory.
      * This field should be made private, so it is hidden from the SDK.
@@ -556,6 +560,9 @@
                 case R.styleable.ViewGroup_layoutMode:
                     setLayoutMode(a.getInt(attr, LAYOUT_MODE_UNDEFINED));
                     break;
+                case R.styleable.ViewGroup_transitionGroup:
+                    setTransitionGroup(a.getBoolean(attr, false));
+                    break;
             }
         }
 
@@ -2288,6 +2295,41 @@
     }
 
     /**
+     * Returns true if this ViewGroup should be considered as a single entity for removal
+     * when executing an Activity transition. If this is false, child elements will move
+     * 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)
+     */
+    public boolean isTransitionGroup() {
+        if ((mGroupFlags & FLAG_IS_TRANSITION_GROUP_SET) != 0) {
+            return ((mGroupFlags & FLAG_IS_TRANSITION_GROUP) != 0);
+        } else {
+            return getBackground() != null;
+        }
+    }
+
+    /**
+     * Changes whether or not this ViewGroup should be treated as a single entity during
+     * ActivityTransitions.
+     * @param isTransitionGroup Whether or not the ViewGroup should be treated as a unit
+     *                          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;
+        if (isTransitionGroup) {
+            mGroupFlags |= FLAG_IS_TRANSITION_GROUP;
+        } else {
+            mGroupFlags &= ~FLAG_IS_TRANSITION_GROUP;
+        }
+    }
+
+    /**
      * {@inheritDoc}
      */
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5aa46f3..ccb85a6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2592,7 +2592,7 @@
                         R.attr.accessibilityFocusedDrawable, value, true);
                 if (resolved) {
                     mAttachInfo.mAccessibilityFocusDrawable =
-                        mView.mContext.getResources().getDrawable(value.resourceId);
+                        mView.mContext.getDrawable(value.resourceId);
                 }
             }
             return mAttachInfo.mAccessibilityFocusDrawable;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2f62431..11740ab 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -1039,7 +1040,7 @@
      */
     public void setBackgroundDrawableResource(int resid)
     {
-        setBackgroundDrawable(mContext.getResources().getDrawable(resid));
+        setBackgroundDrawable(mContext.getDrawable(resid));
     }
 
     /**
@@ -1374,8 +1375,41 @@
     /**
      * Set options that can affect the transition behavior within this window.
      * @param options Options to set or null for none
+     * @hide
      */
-    public void setTransitionOptions(Bundle options) {
-        throw new UnsupportedOperationException();
+    public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
+    }
+
+    /**
+     * A callback for Activity transitions to be told when the shared element is ready to be shown
+     * and start the transition to its target location.
+     * @hide
+     */
+    public interface SceneTransitionListener {
+        void enterSharedElement(Bundle transitionArgs);
+        void nullPendingTransition();
+        void convertFromTranslucent();
+        void convertToTranslucent();
+    }
+
+    /**
+     * 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.
+     *
+     * @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
+     */
+    public void setEarlyBackgroundTransition(boolean fadeEarly) {
+    }
+
+    /**
+     * Start the exit transition.
+     * @hide
+     */
+    public void startExitTransition(ActivityOptions activityOptions) {
     }
 }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4d8975c..13febe9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1604,7 +1604,7 @@
     }
 
     private void useDefaultSelector() {
-        setSelector(getResources().getDrawable(
+        setSelector(getContext().getDrawable(
                 com.android.internal.R.drawable.list_selector_background));
     }
 
@@ -2616,7 +2616,7 @@
      * @attr ref android.R.styleable#AbsListView_listSelector
      */
     public void setSelector(int resID) {
-        setSelector(getResources().getDrawable(resID));
+        setSelector(getContext().getDrawable(resID));
     }
 
     public void setSelector(Drawable sel) {
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 3c88e94..5b80648 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -80,17 +80,17 @@
 
         mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
         if (mDial == null) {
-            mDial = r.getDrawable(com.android.internal.R.drawable.clock_dial);
+            mDial = context.getDrawable(com.android.internal.R.drawable.clock_dial);
         }
 
         mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour);
         if (mHourHand == null) {
-            mHourHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
+            mHourHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
         }
 
         mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);
         if (mMinuteHand == null) {
-            mMinuteHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
+            mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
         }
 
         mCalendar = new Time();
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 34cfea5..10e56c7 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -322,7 +322,7 @@
             CharSequence grpName, CharSequence description, boolean dangerous) {
         LayoutInflater inflater = (LayoutInflater)context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
-        Drawable icon = context.getResources().getDrawable(dangerous
+        Drawable icon = context.getDrawable(dangerous
                 ? R.drawable.ic_bullet_key_permission : R.drawable.ic_text_dot);
         return getPermissionItemViewOld(context, inflater, grpName,
                 description, dangerous, icon);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 259c66b9..eb232fd 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -366,7 +366,7 @@
      * @attr ref android.R.styleable#PopupWindow_popupBackground
      */
     public void setDropDownBackgroundResource(int id) {
-        mPopup.setBackgroundDrawable(getResources().getDrawable(id));
+        mPopup.setBackgroundDrawable(getContext().getDrawable(id));
     }
     
     /**
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index c6be6dd..ea60abb 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1029,7 +1029,7 @@
 
         @Override
         public void setSelectedDateVerticalBar(int resourceId) {
-            Drawable drawable = mDelegator.getResources().getDrawable(resourceId);
+            Drawable drawable = mDelegator.getContext().getDrawable(resourceId);
             setSelectedDateVerticalBar(drawable);
         }
 
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 78b1b75..1533510 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -123,7 +123,7 @@
 
         Drawable d = null;
         if (mCheckMarkResource != 0) {
-            d = getResources().getDrawable(mCheckMarkResource);
+            d = getContext().getDrawable(mCheckMarkResource);
         }
         setCheckMarkDrawable(d);
     }
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index b22088c..4298545 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -186,7 +186,7 @@
 
         Drawable d = null;
         if (mButtonResource != 0) {
-            d = getResources().getDrawable(mButtonResource);
+            d = getContext().getDrawable(mButtonResource);
         }
         setButtonDrawable(d);
     }
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 30752e0..fa37443 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -136,8 +136,8 @@
      */
     public EdgeEffect(Context context) {
         final Resources res = context.getResources();
-        mEdge = res.getDrawable(R.drawable.overscroll_edge);
-        mGlow = res.getDrawable(R.drawable.overscroll_glow);
+        mEdge = context.getDrawable(R.drawable.overscroll_edge);
+        mGlow = context.getDrawable(R.drawable.overscroll_glow);
 
         mEdgeHeight = mEdge.getIntrinsicHeight();
         mGlowHeight = mGlow.getIntrinsicHeight();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 11dbce8..ea62bbe 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1679,7 +1679,7 @@
 
     private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
         if (mCursorDrawable[cursorIndex] == null)
-            mCursorDrawable[cursorIndex] = mTextView.getResources().getDrawable(
+            mCursorDrawable[cursorIndex] = mTextView.getContext().getDrawable(
                     mTextView.mCursorDrawableRes);
 
         if (mTempRect == null) mTempRect = new Rect();
@@ -2969,7 +2969,7 @@
                 positionY += mContentView.getMeasuredHeight();
 
                 // Assumes insertion and selection handles share the same height
-                final Drawable handle = mTextView.getResources().getDrawable(
+                final Drawable handle = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRes);
                 positionY += handle.getIntrinsicHeight();
             }
@@ -3546,7 +3546,7 @@
 
         private InsertionHandleView getHandle() {
             if (mSelectHandleCenter == null) {
-                mSelectHandleCenter = mTextView.getResources().getDrawable(
+                mSelectHandleCenter = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRes);
             }
             if (mHandle == null) {
@@ -3592,11 +3592,11 @@
 
         private void initDrawables() {
             if (mSelectHandleLeft == null) {
-                mSelectHandleLeft = mTextView.getContext().getResources().getDrawable(
+                mSelectHandleLeft = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleLeftRes);
             }
             if (mSelectHandleRight == null) {
-                mSelectHandleRight = mTextView.getContext().getResources().getDrawable(
+                mSelectHandleRight = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRightRes);
             }
         }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 58e4e86..572302a4 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -642,7 +642,7 @@
 
         if (mResource != 0) {
             try {
-                d = rsrc.getDrawable(mResource);
+                d = mContext.getDrawable(mResource);
             } catch (Exception e) {
                 Log.w("ImageView", "Unable to find resource: " + mResource, e);
                 // Don't try again.
@@ -655,7 +655,7 @@
                     // Load drawable through Resources, to get the source density information
                     ContentResolver.OpenResourceIdResult r =
                             mContext.getContentResolver().getResourceId(mUri);
-                    d = r.r.getDrawable(r.id);
+                    d = r.r.getDrawable(r.id, mContext.getTheme());
                 } catch (Exception e) {
                     Log.w("ImageView", "Unable to open content: " + mUri, e);
                 }
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index a4f758c..74b41c9 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -155,7 +155,7 @@
      */
     public void setImageToDefault() {
         if (mDefaultAvatar == null) {
-            mDefaultAvatar = getResources().getDrawable(R.drawable.ic_contact_picture);
+            mDefaultAvatar = mContext.getDrawable(R.drawable.ic_contact_picture);
         }
         setImageDrawable(mDefaultAvatar);
     }
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 3791258..1eedc5d 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1059,7 +1059,7 @@
 
         SpannableStringBuilder ssb = new SpannableStringBuilder("   "); // for the icon
         ssb.append(hintText);
-        Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId());
+        Drawable searchIcon = getContext().getDrawable(getSearchIconId());
         int textSize = (int) (mQueryTextView.getTextSize() * 1.25);
         searchIcon.setBounds(0, 0, textSize, textSize);
         ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index bdaaa01..64a1574 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -168,7 +168,7 @@
         // Lookup and set the expand action icon.
         TypedValue outTypedValue = new TypedValue();
         mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
-        Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
+        Drawable drawable = mContext.getDrawable(outTypedValue.resourceId);
         activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
         activityChooserView.setProvider(this);
 
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index eabe1a3..9601d4a 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -281,7 +281,7 @@
      * @attr ref android.R.styleable#Spinner_popupBackground
      */
     public void setPopupBackgroundResource(int resId) {
-        setPopupBackgroundDrawable(getContext().getResources().getDrawable(resId));
+        setPopupBackgroundDrawable(getContext().getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index c44d431..c8917e0 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -529,7 +529,7 @@
                 return drawable;
             }
             // Not cached, find it by resource ID
-            drawable = mProviderContext.getResources().getDrawable(resourceId);
+            drawable = mProviderContext.getDrawable(resourceId);
             // Stick it in the cache, using the URI as key
             storeInIconCache(drawableUri, drawable);
             return drawable;
@@ -563,7 +563,7 @@
                 OpenResourceIdResult r =
                     mProviderContext.getContentResolver().getResourceId(uri);
                 try {
-                    return r.r.getDrawable(r.id);
+                    return r.r.getDrawable(r.id, mContext.getTheme());
                 } catch (Resources.NotFoundException ex) {
                     throw new FileNotFoundException("Resource does not exist: " + uri);
                 }
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index c9a1ca4..2a5fb15 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -417,7 +417,7 @@
      * @attr ref android.R.styleable#Switch_track
      */
     public void setTrackResource(int resId) {
-        setTrackDrawable(getContext().getResources().getDrawable(resId));
+        setTrackDrawable(getContext().getDrawable(resId));
     }
 
     /**
@@ -453,7 +453,7 @@
      * @attr ref android.R.styleable#Switch_thumb
      */
     public void setThumbResource(int resId) {
-        setThumbDrawable(getContext().getResources().getDrawable(resId));
+        setThumbDrawable(getContext().getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 568b3e6a..47a5449 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -120,28 +120,27 @@
         setChildrenDrawingOrderEnabled(true);
 
         final Context context = mContext;
-        final Resources resources = context.getResources();
 
         // Tests the target Sdk version, as set in the Manifest. Could not be set using styles.xml
         // in a values-v? directory which targets the current platform Sdk version instead.
         if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
             // Donut apps get old color scheme
             if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
+                mLeftStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_left_v4);
             }
             if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
+                mRightStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right_v4);
             }
         } else {
             // Use modern color scheme for Eclair and beyond
             if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
+                mLeftStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_left);
             }
             if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
+                mRightStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right);
             }
         }
@@ -246,7 +245,7 @@
      * divider.
      */
     public void setDividerDrawable(int resId) {
-        setDividerDrawable(getResources().getDrawable(resId));
+        setDividerDrawable(mContext.getDrawable(resId));
     }
     
     /**
@@ -267,7 +266,7 @@
      * left strip drawable
      */
     public void setLeftStripDrawable(int resId) {
-        setLeftStripDrawable(getResources().getDrawable(resId));
+        setLeftStripDrawable(mContext.getDrawable(resId));
     }
 
     /**
@@ -288,7 +287,7 @@
      * right strip drawable
      */
     public void setRightStripDrawable(int resId) {
-        setRightStripDrawable(getResources().getDrawable(resId));
+        setRightStripDrawable(mContext.getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 15606a45..3be23b7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2073,11 +2073,11 @@
      */
     @android.view.RemotableViewMethod
     public void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) {
-        final Resources resources = getContext().getResources();
-        setCompoundDrawablesWithIntrinsicBounds(left != 0 ? resources.getDrawable(left) : null,
-                top != 0 ? resources.getDrawable(top) : null,
-                right != 0 ? resources.getDrawable(right) : null,
-                bottom != 0 ? resources.getDrawable(bottom) : null);
+        final Context context = getContext();
+        setCompoundDrawablesWithIntrinsicBounds(left != 0 ? context.getDrawable(left) : null,
+                top != 0 ? context.getDrawable(top) : null,
+                right != 0 ? context.getDrawable(right) : null,
+                bottom != 0 ? context.getDrawable(bottom) : null);
     }
 
     /**
@@ -2247,12 +2247,12 @@
     @android.view.RemotableViewMethod
     public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end,
             int bottom) {
-        final Resources resources = getContext().getResources();
+        final Context context = getContext();
         setCompoundDrawablesRelativeWithIntrinsicBounds(
-                start != 0 ? resources.getDrawable(start) : null,
-                top != 0 ? resources.getDrawable(top) : null,
-                end != 0 ? resources.getDrawable(end) : null,
-                bottom != 0 ? resources.getDrawable(bottom) : null);
+                start != 0 ? context.getDrawable(start) : null,
+                top != 0 ? context.getDrawable(top) : null,
+                end != 0 ? context.getDrawable(end) : null,
+                bottom != 0 ? context.getDrawable(bottom) : null);
     }
 
     /**
@@ -4385,8 +4385,8 @@
         if (error == null) {
             setError(null, null);
         } else {
-            Drawable dr = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.indicator_input_error);
+            Drawable dr = getContext().getDrawable(
+                    com.android.internal.R.drawable.indicator_input_error);
 
             dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
             setError(error, dr);
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 347f957..0a80495 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -1081,7 +1081,7 @@
 
         @Override
         public Tab setIcon(int resId) {
-            return setIcon(mContext.getResources().getDrawable(resId));
+            return setIcon(mContext.getDrawable(resId));
         }
 
         @Override
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index 8fc99c7..b0e0373 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -256,13 +256,13 @@
     private Drawable getIconDrawable() {
         if (mRoute.isConnecting()) {
             if (mMediaRouteConnectingDrawable == null) {
-                mMediaRouteConnectingDrawable = getContext().getResources().getDrawable(
+                mMediaRouteConnectingDrawable = getContext().getDrawable(
                         R.drawable.ic_media_route_connecting_holo_dark);
             }
             return mMediaRouteConnectingDrawable;
         } else {
             if (mMediaRouteOnDrawable == null) {
-                mMediaRouteOnDrawable = getContext().getResources().getDrawable(
+                mMediaRouteOnDrawable = getContext().getDrawable(
                         R.drawable.ic_media_route_on_holo_dark);
             }
             return mMediaRouteOnDrawable;
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index 7ca6c1b..ed676bb 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -163,7 +163,7 @@
 
     public MenuItem setIcon(int iconRes) {
         mIconResId = iconRes;
-        mIconDrawable = mContext.getResources().getDrawable(iconRes);
+        mIconDrawable = mContext.getDrawable(iconRes);
         return this;
     }
 
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index b7cb0de..b776226 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -1121,7 +1121,7 @@
             }
             
             if (iconRes > 0) {
-                mHeaderIcon = r.getDrawable(iconRes);
+                mHeaderIcon = getContext().getDrawable(iconRes);
             } else if (icon != null) {
                 mHeaderIcon = icon;
             }
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 4d0a326..61dcaca 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -385,7 +385,7 @@
         }
 
         if (mIconResId != NO_ICON) {
-            Drawable icon =  mMenu.getResources().getDrawable(mIconResId);
+            Drawable icon =  mMenu.getContext().getDrawable(mIconResId);
             mIconResId = NO_ICON;
             mIconDrawable = icon;
             return icon;
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index ff2c625..1273c4d 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -697,7 +697,7 @@
     }
 
     public void setIcon(int resId) {
-        setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+        setIcon(resId != 0 ? mContext.getDrawable(resId) : null);
     }
 
     public boolean hasIcon() {
@@ -712,7 +712,7 @@
     }
 
     public void setLogo(int resId) {
-        setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+        setLogo(resId != 0 ? mContext.getDrawable(resId) : null);
     }
 
     public boolean hasLogo() {
@@ -1417,7 +1417,7 @@
 
         public void setUpIndicator(int resId) {
             mUpIndicatorRes = resId;
-            mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
+            mUpView.setImageDrawable(resId != 0 ? getContext().getDrawable(resId) : null);
         }
 
         @Override
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index 8368136..7483e75 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -72,8 +72,8 @@
 
     private void init(Context context) {
         final Resources res = context.getResources();
-        mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
-        mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
+        mShiftIcon = context.getDrawable(R.drawable.sym_keyboard_shift);
+        mShiftLockIcon = context.getDrawable(R.drawable.sym_keyboard_shift_locked);
         sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
                 R.dimen.password_keyboard_spacebar_vertical_correction);
     }
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index cd1ccd3..93ea5b3 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -234,7 +234,7 @@
         mMagneticTargets = a.getBoolean(R.styleable.GlowPadView_magneticTargets, mMagneticTargets);
 
         int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable);
-        Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null;
+        Drawable pointDrawable = pointId != 0 ? context.getDrawable(pointId) : null;
         mGlowRadius = a.getDimension(R.styleable.GlowPadView_glowRadius, 0.0f);
 
         TypedValue outValue = new TypedValue();
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 3116955..5d49204 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -141,7 +141,8 @@
     *needsDetach = false;
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     if (env == NULL) {
-        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
+        JavaVMAttachArgs args = {
+            JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL };
         JavaVM* vm = AndroidRuntime::getJavaVM();
         int result = vm->AttachCurrentThread(&env, (void*) &args);
         if (result != JNI_OK) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 315b119..7ea08af 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -583,7 +583,7 @@
     <!-- =============================================================== -->
     <eat-comment />
 
-    <!-- Used for permissions that provide access to the user voicemail box. -->
+    <!-- Used for permissions that provide access to device alarms. -->
     <permission-group android:name="android.permission-group.DEVICE_ALARMS"
         android:label="@string/permgrouplab_deviceAlarms"
         android:icon="@drawable/perm_group_device_alarms"
@@ -1061,7 +1061,7 @@
     <!-- =========================================== -->
     <eat-comment />
 
-    <!-- Used for permissions that are associated with accessing and modifyign
+    <!-- Used for permissions that are associated with accessing and modifying
          telephony state: placing calls, intercepting outgoing calls, reading
          and modifying the phone state. -->
     <permission-group android:name="android.permission-group.PHONE_CALLS"
diff --git a/core/res/res/drawable-hdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-hdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..8d529b8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_search_api_holo_light.png b/core/res/res/drawable-hdpi/ic_search_api_holo_light.png
index 72e207b..8b15ecb 100644
--- a/core/res/res/drawable-hdpi/ic_search_api_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..32062a6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png
index 3481c98..d2b2d21 100644
--- a/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search.png b/core/res/res/drawable-mdpi/ic_search.png
index 4be72f1..66145e0 100644
--- a/core/res/res/drawable-mdpi/ic_search.png
+++ b/core/res/res/drawable-mdpi/ic_search.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-mdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..4771a56
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search_api_holo_light.png b/core/res/res/drawable-mdpi/ic_search_api_holo_light.png
index f2e26f8..60a55f8 100644
--- a/core/res/res/drawable-mdpi/ic_search_api_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search.png b/core/res/res/drawable-mdpi/ic_voice_search.png
index 73c6be6..b2535fb 100644
--- a/core/res/res/drawable-mdpi/ic_voice_search.png
+++ b/core/res/res/drawable-mdpi/ic_voice_search.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..fcc2105
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png
index 71d838e..b516b95 100644
--- a/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search.png b/core/res/res/drawable-xhdpi/ic_search.png
index 998f91b..738a392 100644
--- a/core/res/res/drawable-xhdpi/ic_search.png
+++ b/core/res/res/drawable-xhdpi/ic_search.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-xhdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..b0d7acf
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png b/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png
index a4cdf1c..c9626a0 100644
--- a/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_category_default.png b/core/res/res/drawable-xhdpi/ic_search_category_default.png
index 7d5170e..351cfe0 100644
--- a/core/res/res/drawable-xhdpi/ic_search_category_default.png
+++ b/core/res/res/drawable-xhdpi/ic_search_category_default.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search.png b/core/res/res/drawable-xhdpi/ic_voice_search.png
index c625a36..3f0518b 100644
--- a/core/res/res/drawable-xhdpi/ic_voice_search.png
+++ b/core/res/res/drawable-xhdpi/ic_voice_search.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..eb6e5fa
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png
index c332ba0..c6b40bb 100644
--- a/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..eb30465
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_search_api_holo_light.png b/core/res/res/drawable-xxhdpi/ic_search_api_holo_light.png
new file mode 100644
index 0000000..bc14415
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..813048c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_light.png
new file mode 100644
index 0000000..8addde0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index b550545..49d13f2 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Laat die program toe om enige geïnstalleer mediadekodeerder te gebruik om te kan dekodeer vir terugspeel."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"bestuur vertroude eiebewyse"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Laat die program CA-sertifikate as vertroude eiebewyse installeer en deïnstalleer."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bind aan ledige dienste"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Laat die program met programgedefinieerde ledige dienste omgaan."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lees/skryf na bronne wat diag besit"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Laat die program toe om na enige hulpbron wat deur die diag-groep besit word, te skryf, byvoorbeeld lêers in /dev. Dit kan potensieel stelselstabiliteit en sekuriteit affekteer. Dit moet NET gebruik word vir hardewarespesifieke diagnose deur die vervaardiger of operateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 861ae68..c8daf99 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"ከስራ ፈት አገልግሎቶች ጋር ይሰሩ"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"መተግበሪያው በመተግበሪያ ከተገለጹ ስራ ፈት አገልግሎቶች ጋር እንዲስተጋብር ያስችላል።"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"በdiag ባለቤትነት ያሉ ንብረቶችን አንብብ/ፃፍ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"በዲያግ ቡድን ባለቤትነት ወደ አለ ማንኛውም ንብረት ለምሳሌ በ/dev ያሉ ፋይሎች ለማንበብ እና ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። ይህ በመሰረቱ የስርዓት መረጋጋትን እና ደህንነትን ሊጎዳ ይችላል። ይህ ውስን የሀርድዌር-ተኮር ዲያግኖስቲክስ በአምራቹ ወይም ከዋኙ ብቻ መሆን አለበት።"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"የመተግበሪያ ምንዝሮችን አንቃ ወይም አቦዝን"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index e20b7b4..fca2a18a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"الالتزام بالخدمات الخاملة"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"للسماح للتطبيق بالتفاعل مع الخدمات الخاملة التي يحددها التطبيق."</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-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 1dbb050..064a2ac 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -423,6 +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="7521398788076342815">"обвързване с услуги при неактивност"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Разрешава на приложението да взаимодейства с дефинирани от приложения услуги при неактивност."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"четене/запис в ресурси, притежавани от diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Разрешава на приложението да чете и записва във всеки ресурс, притежаван от групата diag, например файловете в /dev. Това потенциално може да засегне стабилността и сигурността на системата. То трябва да се използва САМО за диагностика, конкретно за хардуера, от страна на производителя или оператора."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"активиране или деактивиране на компоненти на приложенията"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8eadf2c..9b8faaf 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet que l\'aplicació utilitzi qualsevol descodificador de mitjans instal·lat per descodificar per a la reproducció."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestiona les credencials de confiança"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet que l\'aplicació instal·li i desinstal·li certificats de CA com a credencials de confiança."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"vincula als serveis inactius"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Permet que l\'aplicació interaccioni amb els serveis inactius definits per l\'aplicació."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"llegir/escriure recursos propietat de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet que l\'aplicació llegeixi i escrigui a qualsevol recurs propietat del grup diag; per exemple, els fitxers de /dev. Això podria afectar l\'estabilitat i la seguretat del sistema. NOMÉS l\'hauria d\'utilitzar el fabricant o l\'operador per a diagnòstics específics de maquinari."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 8cf6d8d..3163607 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikaci používat libovolný nainstalovaný dekodér médií k dekódování při přehrávání."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"správa důvěryhodných identifikačních údajů"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Umožňuje aplikaci instalovat a odinstalovat certifikáty CA jako důvěryhodné identifikační údaje."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"napojit se na nečinné služby"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Umožňuje aplikaci ovlivňovat nečinné služby definované aplikacemi."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čtení nebo zápis do prostředků funkce diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikaci číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat POUZE výrobce či operátor pro diagnostiku hardwaru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 565578f..6420fdd 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tillader, at appen bruger enhver installeret medieafkoder til at afkode til afspilning."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrer pålidelige logonoplysninger"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tillader, at appen installerer og afinstallerer CA-certifikater som pålidelige loginoplysninger."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"knyt til dvaletjenester"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Tillader, at appen interagerer med dvaletjenester, som defineres af applikationen."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"læs/skriv til ressourcer ejet af diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillader, at appen kan læse og skrive til alle ressourcer, der ejes af diag-gruppen,  f.eks. filer i /dev. Dette kan muligvis påvirke systemets stabilitet og sikkerhed. Dette bør KUN bruges til hardwarespecifik diagnosticering, som foretages af producenten eller udbyderen."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index b244fd9..078aa90 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ermöglicht der App, alle installierten Mediendecodierer zur Wiedergabe zu verwenden."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Vertrauenswürdige Anmeldedaten verwalten"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ermöglicht der App, CA-Zertifikate als vertrauenswürdige Anmeldedaten zu installieren und zu deinstallieren."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"An inaktive Dienste binden"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Ermöglicht der App, mit anwendungsdefinierten inaktiven Diensten zu interagieren"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lese-/Schreibberechtigung für zu Diagnosegruppe gehörige Elemente"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ermöglicht der App, alle Elemente in der Diagnosegruppe zu lesen und zu bearbeiten, etwa Dateien in \"/dev\". Dies könnte eine potenzielle Gefährdung für die Stabilität und Sicherheit des Systems darstellen und sollte NUR für hardwarespezifische Diagnosen des Herstellers oder Mobilfunkanbieters verwendet werden."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"App-Komponenten aktivieren oder deaktivieren"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b7050dc..dac6757 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"σύνδεση σε υπηρεσίες αδράνειας"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Επιτρέπει στην εφαρμογή να αλληλεπιδρά με αδρανείς υπηρεσίες που καθορίζονται από την εφαρμογή."</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-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index fdaae8b..50089cb 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bind to idle services"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Allows the app to interact with application-defined idle services."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index fdaae8b..50089cb 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bind to idle services"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Allows the app to interact with application-defined idle services."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1e94bd9..5c1eee4 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrar credenciales de confianza"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que la aplicación instale y desinstale certificados de CA como credenciales de confianza."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"vincular con servicios inactivos"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Permite que la aplicación interaccione con servicios inactivos definidos por la aplicación."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer y escribir a recursos dentro del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar la seguridad y estabilidad del sistema. SOLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 75f1c6d..906df2c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrar credenciales de confianza"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que la aplicación instale y desinstale certificados de CA como credenciales de confianza."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"ocultar para servicios inactivos"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Permite que la aplicación interactúe con servicios inactivos definidos por la aplicación."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer/escribir en los recursos propiedad del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación consulte y escriba en cualquier recurso del grupo de diagnóstico como, por ejemplo, archivos en /dev. Este permiso podría afectar a la seguridad y estabilidad del sistema. SOLO se debe usar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"habilitar o inhabilitar componentes de la aplicación"</string>
@@ -1526,7 +1528,7 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduce un código PIN con una longitud comprendida entre cuatro y ocho dígitos."</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"El código PUK debe tener ocho números."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"El código PUK debe tener 8 números."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a introducir el código PUK correcto. Si introduces un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de crear el patrón"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index dcf38ac..0fb2a12 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Võimaldab rakendusel taasesituseks kasutada mis tahes installitud meediumidekooderit."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"usaldusväärsete mandaatide haldamine"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lubab rakendusel installida ja desinstallida usaldusväärsete mandaatidena CA-sertifikaate."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"sidumine tegevusetute teenustega"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Lubab rakendusel suhelda rakenduse määratud tegevusetute teenustega."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"loe/kirjuta valija allikaid"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Võimaldab rakendusel lugeda valimisrühma mis tahes ressurssi ja sellesse kirjutada (näiteks kaustas /dev olevad failid). See võib mõjutada süsteemi stabiilsust ja turvet. Seda tohiks kasutada tootja või operaator AINULT riistvaraspetsiifiliseks diagnostikaks."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
@@ -1526,7 +1528,7 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kaardi avamine ..."</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Vale PIN-kood."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Sisestage 4–8-numbriline PIN-kood."</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-kood peab sisaldama 8 numbrit."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-kood peab koosnema 8 numbrist."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM jäädavalt."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodid ei ole vastavuses"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liiga palju mustrikatseid"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 465d1e2..57af25e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"اتصال با سرویس‌های غیرفعال"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"به برنامه اجازه می‌دهد با سرویس‌های غیرفعال تعریف شده توسط برنامه تعامل داشته باشد."</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-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5f1ecbd..c5bcda7 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -423,6 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Sallii sovelluksen käyttää mitä tahansa asennettua tietovälineen koodin purkajaa toistoa varten."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"hallinnoi luotettavia varmenteita"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Antaa sovellukselle luvan asentaa ja poistaa luotettavia CA-varmenteita."</string>
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lue diag:in omistamia resursseja / kirjoita resursseihin"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Antaa sovelluksen lukea ja kirjoittaa diag-ryhmän omistamiin resursseihin, esimerkiksi /dev-hakemistossa oleviin tiedostoihin. Tämä voi vaikuttaa järjestelmän vakauteen ja turvallisuuteen. Tämä lupa tulee myöntää VAIN valmistajan tai operaattorin laitteistotesteille."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2375194..5b866c6 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gérer les certificats de confiance"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet à l\'application d\'installer et de désinstaller les certificats CA en tant que certificats de confiance."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"lier aux services inactifs"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Permet à l\'application d\'interagir avec les services inactifs définis par l\'application."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lire ou modifier les ressources appartenant au groupe de diagnostics"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture et en écriture pour toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Cela peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou le fournisseur de services."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants d\'une application"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 685ed04..4ea32f4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gérer les certificats de confiance"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet à l\'application d\'installer et de désinstaller les certificats CA en tant que certificats de confiance."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associer aux services d\'inactivité"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Permettre à l\'application d\'interagir avec les services d\'inactivité définis par des applications"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lecture/écriture dans les ressources appartenant aux diagnostics"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture/écriture concernant toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants de l\'application"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 264a0e5..15ffe52 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"निष्क्रिय सेवाओं से आबद्ध करें"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"ऐप्स को एप्लिकेशन-परिभाषित निष्क्रिय सेवाओं के साथ सहभागिता करने की अनुमति देता है."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"निदान के स्‍वामित्‍व वाले संसाधनों को पढ़ें/लिखें"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ऐप्स को diag समूह के स्‍वामित्‍व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्‍टम की स्‍थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ऐप्स घटकों को सक्षम या अक्षम करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0880d2f..cc52a10 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Aplikaciji omogućuje korištenje bilo kojim instaliranim dekoderom medija za dekodiranje radi reprodukcije."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje pouzdanim vjerodajnicama"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Omogućuje aplikaciji instaliranje i deinstaliranje CA certifikata kao pouzdanih vjerodajnica."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"veži uz usluge u mirovanju"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Omogućuje aplikaciji interakciju s uslugama u mirovanju definiranim aplikacijom."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"pisanje/čitanje u resursima čije je vlasnik dijagnostika"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Aplikaciji omogućuje čitanje i pisanje na bilo koji resurs u vlasništvu dijag. grupe; na primjer, datoteke u sustavu /dev. To bi moglo utjecati na stabilnost sustava i sigurnost. Dozvolu bi trebao upotrebljavati proizvođač ili operater SAMO za dijagnostiku koja se odnosi na hardver."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 5eadb47..60e026f1 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Lehetővé teszi egy alkalmazás számára bármely telepített médiadekóder használatát a lejátszás dekódolásához."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"megbízható tanúsítványok kezelése"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lehetővé teszi az alkalmazás számára a CA tanúsítványok telepítését és eltávolítását."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"csatolás tétlen szolgáltatásokhoz"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Engedélyezi az alkalmazás kommunikációját az alkalmazás által meghatározott, tétlen szolgáltatásokkal."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"a diag tulajdonában lévő erőforrások olvasása és írása"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lehetővé teszi egy alkalmazás számára, hogy olvassa és írja a diagnosztikai csoport minden erőforrását, például a /dev könyvtárban lévő fájlokat. Ez potenciálisan befolyásolhatja a rendszer stabilitását és biztonságát, ezért CSAK a gyártó vagy a szolgáltató használhatja hardverspecifikus diagnosztizálásra."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"alkalmazáskomponensek be- és kikapcsolása"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 1a5228d..534c570 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"կապակցել ոչ ակտիվ ծառայությունների հետ"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Թույլ է տալիս ծրագրին փոխգործակցել ոչ ակտիվ ծառայությունների հետ, որոնցում ծրագրերը մեծ դեր ունեն:"</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-in/strings.xml b/core/res/res/values-in/strings.xml
index 0e1d5b6..c7a8d36 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Mengizinkan apl menggunakan pengawasandi media apa pun yang terpasang guna mengawasandikan media untuk diputar."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"kelola kredensial tepercaya"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Izinkan aplikasi memasang dan mencopot pemasangan sertifikat CA sebagai kredensial tepercaya."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"mengikat ke layanan nganggur"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Memungkinkan aplikasi berinteraksi dengan layanan nganggur yang ditetapkan oleh aplikasi."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber daya yang dimiliki oleh diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Mengizinkan apl membaca dan menulis ke sumber daya apa pun yang dimiliki oleh grup diag; misalnya, file dalam /dev. Izin ini berpotensi memengaruhi kestabilan dan keamanan sistem. Sebaiknya ini HANYA digunakan untuk diagnosis khusus perangkat keras oleh pabrikan atau operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 75c887ef..56ec024 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Consente all\'applicazione di utilizzare qualsiasi decoder multimediale installato per la decodifica ai fini della riproduzione."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestione di credenziali attendibili"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Consente all\'app di installare e disinstallare certificati CA come credenziali attendibili."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associazione a servizi non disponibili"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Consente all\'app di interagire con i servizi non disponibili definiti dall\'applicazione."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lettura/scrittura risorse di proprietà di diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Consente all\'applicazione di leggere le risorse del gruppo diag e scrivere in esse, ad esempio i file in /dev. Ciò potrebbe influire su stabilità e sicurezza del sistema. Dovrebbe essere utilizzata SOLTANTO per diagnostiche specifiche dell\'hardware effettuate dal produttore o dall\'operatore."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"attivazione/disattivazione componenti applicazioni"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 008d078..8bd1b0c 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"אגד עם שירותים במצב לא פעיל"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"מאפשר אינטראקטיביות של האפליקציה עם שירותים המוגדרים על ידי האפליקציה כבמצב לא פעיל."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"‏קרא/כתוב במשאבים בבעלות diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏מאפשר לאפליקציה לקרוא ולכתוב בכל משאב שבבעלות קבוצת ה-diag; לדוגמה, קבצים ב-‎/dev. פעולה זו עשויה להשפיע על היציבות והאבטחה של המערכת. אפשרות זו צריכה לשמש רק את היצרן או המפעיל, לצורך אבחונים ספציפיים לחומרה."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"הפעלה או השבתה של רכיבי אפליקציות"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4a994b2..209c7fd 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"アイドルサービスへのバインディング"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"アプリ定義のアイドルサービスとの通信をアプリに許可します。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"diagが所有するリソースの読み書き"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"diagグループが所有するリソース(/dev内のファイルなど)の読み書きをアプリに許可します。許可すると、システムの安定性とセキュリティに影響が生じる可能性があります。メーカー/通信事業者によるハードウェア固有の診断以外には使用しないでください。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"アプリのコンポーネントの有効/無効化"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 7e13e96..12f56a3 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -423,6 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"აპს დასაკრავად შეეძლება გამოიყენოს ნებისმიერი დაყენებული მედია დეკოდერი."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"სანდო მტკიცებულებების მართვა"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"აპისთვის ნების დართვა, მოახდინოს CA სერტიფიკატების სანდო მტკიცებულებებად ინსტალაცია და დეინსტალაცია."</string>
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <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-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 38d518a..867d7af 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"ភ្ជាប់​​ទៅ​​សេវាកម្ម​ទំនេរ"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"ឲ្យ​កម្មវិធី​ទាក់ទង​ជា​មួយ​សេវាកម្ម​ទំនេរ​ដែល​បាន​កំណត់​ដោយ​កម្មវិធី។"</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-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a51e605..c5e6a4a 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"유휴 서비스에 연결"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"애플리케이션 정의 유휴 서비스와 앱이 상호작용하도록 허용합니다."</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-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index c7aed51..4fca324 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -423,6 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ອະນຸຍາດໃຫ້ແອັບຯໃຊ້ທຸກຕົວຖອດລະຫັດສື່ທີ່ຕິດຕັ້ງໄວ້ແລ້ວ ເພື່ອການຖອດລະຫັດການຫຼິ້ນໄຟລ໌ຕ່າງໆ."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"ຈັດການໜັງສືຮັບຮອງທີ່ເຊື່ອຖືໄດ້."</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯ ຕິດຕັ້ງ ແລະ ຖອນການຕິດຕັ້ງໃບຢັ້ງຢືນ CA ທີ່ເປັນໃບຮັບຮອງທີ່ເຊື່ອຖືໄດ້."</string>
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <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-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 6b5191d..ac893c7 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Leidžiama programai naudoti bet kurį įdiegtą medijos dekoderį norint iššifruoti atkūrimą."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"tvarkyti patikimus prisijungimo duomenis"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Programoje galima įdiegti ir iš jos pašalinti CA sertifikatus kaip patikimus prisijungimo duomenis."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"susaistyti su neaktyviomis paslaugomis"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Programai leidžiama sąveikauti su programoje apibrėžtomis neaktyviomis paslaugomis."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"skaityti / rašyti ištekliuose, priklausančiuose diagnostikai"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Leidžiama programai skaityti ir rašyti visuose diagnostikos grupei priklausančiuose ištekliuose, pvz., failuose, esančiuose /dev. Tai gali paveikti sistemos stabilumą ir saugą. Tai turėtų būti naudojama TIK gamintojui ar operatoriui atliekant aparatinės įrangos diagnostiką."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 74022a9..bdc7d60 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ļauj lietotnei izmantot jebkuru instalētu multivides failu dekodētāju, lai dekodētu failus atskaņošanai."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Uzticamo akreditācijas datu pārvaldība"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ļauj lietotnei instalēt un atinstalēt CA sertifikātus kā uzticamus akreditācijas datus."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"saistīšana ar neaktīviem pakalpojumiem"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Ļauj lietotnei mijiedarboties ar lietojumprogrammā noteiktiem neaktīviem pakalpojumiem."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lasīt grupas “diag” resursus un rakstīt tajos"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ļauj lietotnei lasīt un rakstīt jebkurā resursā, kas pieder diagnostikas grupai, piemēram, failiem mapē /dev. Tas var ietekmēt sistēmas stabilitāti un drošību. Var izmantot ražotājs vai operators TIKAI konkrētas aparatūras diagnostikai."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 82cdab6..e0095db 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"идэвхгүй үйлчилгээнүүдтэй холбогдох"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Аппликешн-р тодорхойлогдох идэвхгүй үйлчилгээнүүдтэй харилцах боломжийг апп-д олгоно."</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-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index f9d005d..85706b2 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -423,6 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Membenarkan apl untuk menggunakan sebarang penyahkod media yang dipasangkan untuk menyahkod main semula."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"urus bukti kelayakan yang dipercayai"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Membenarkan apl memasang dan menyahpasang sijil CA sebagai bukti kelayakan yang dipercayai."</string>
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber yang dimiliki oleh diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Membenarkan apl membaca dan menulis ke sebarang sumber yang dimiliki oleh kumpulan diag; contohnya, fail dalam /dev. Hal ini berpotensi menjejaskan kestabilan dan keselamatan sistem. Perkara ini seharusnya HANYA digunakan untuk diagnosis khusus perkakasan oleh pengilang atau pengendali."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen apl"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index e6b29c2..ab7255b 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Lar appen bruke en hvilken som helst installert mediedekoder for å dekode for avspilling."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrer pålitelig legitimasjon"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lar appen installere og avinstallere CA-sertifikater som pålitelig legitimasjon."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"knytt til inaktive tjenester"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Lar appen samhandle med app-definerte inaktive apptjenester."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lese/skrive ressurser eid av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lar appen lese og skrive til alle ressurser som eies av gruppen «diag», som for eksempel filer i /dev. Dette kan potensielt påvirke systemets sikkerhet og stabilitet. Dette bør BARE brukes av produsenten eller operatøren til maskinvarespesifikk diagnostikk."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3c0ba73..da2946a 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Hiermee kan de app alle geïnstalleerde mediadecoders gebruiken om te decoderen voor het afspelen."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"vertrouwde inloggegevens beheren"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Hiermee kan de app CA-certificaten installeren en verwijderen als vertrouwde inloggegevens."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"koppelen aan inactieve services"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Staat interactie toe tussen de app en door de app gedefinieerde inactieve services."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lezen/schrijven naar bronnen van diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Hiermee kan de app lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of provider."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"componenten van apps in- of uitschakelen"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 96f3b39..cd08739 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Pozwala aplikacji na użycie dowolnego zainstalowanego dekodera multimediów do odtwarzania."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"zarządzanie zaufanymi danymi uwierzytelniającymi"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Zezwala aplikacji na instalowanie i odinstalowywanie certyfikatów CA jako zaufanych danych uwierzytelniających."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"powiązanie z nieaktywnymi usługami"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Umożliwia aplikacji interakcję ze zdefiniowanymi przez nią nieaktywnymi usługami"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"czytanie/zapisywanie w zasobach należących do diagnostyki"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pozwala aplikacji na czytanie i zapisywanie wszystkich zasobów należących do grupy diagnostyki, na przykład plików w katalogu /dev. Może to potencjalnie wpłynąć na stabilność i bezpieczeństwo systemu. Powinno być wykorzystywane WYŁĄCZNIE do diagnozowania sprzętu przez producenta lub operatora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 261525c..bc98392 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que a aplicação utilize qualquer descodificador de multimédia instalado para descodificar a reprodução."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gerir credenciais fidedignas"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que a aplicação instale e desinstale certificados da AC (Autoridade de certificação) como credenciais fidedignas."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associar a serviços inativos"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Permite que a aplicação interaja com serviços inativos definidos pela aplicação."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/escrever em recursos propriedade de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite à aplicação ler e escrever em qualquer recurso que seja propriedade do grupo diag; por exemplo, ficheiros em /dev. Isto pode potencialmente afetar a estabilidade e a segurança do sistema e deve ser utilizado APENAS para diagnósticos específicos do hardware pelo fabricante ou pelo operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar componentes da aplicação"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 6a80a78..1d8b55b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -423,6 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que o aplicativo use qualquer decodificador de mídia instalado para reprodução."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gerenciar credenciais confiáveis"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que o aplicativo instale e desinstale certificados CA como credenciais confiáveis."</string>
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/gravar em recursos pertencentes ao diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo de diagnósticos, por exemplo, arquivos in/dev. Isso pode afetar a estabilidade e a segurança do sistema. Esse recurso deve ser usado APENAS para diagnósticos específicos do hardware realizados pelo fabricante ou pela operadora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 87550879..fdd26ca 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -678,6 +678,10 @@
     <skip />
     <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
     <skip />
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leger/scriver en resursas che appartegnan a diagnostics"</string>
     <!-- no translation found for permdesc_diagnostic (6608295692002452283) -->
     <skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b222103..dc1aeda 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -423,6 +423,10 @@
     <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>
+    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (3062157929989572890) -->
+    <skip />
     <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>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activare sau dezactivare a componentelor aplicaţiei"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c28a019..652dba5 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -423,6 +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="7521398788076342815">"привязка неактивных сервисов"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Приложение сможет взаимодействовать с определенными неактивными сервисами."</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 399eeee..f06e575 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikácii používať na reprodukciu ľubovoľný nainštalovaný dekódovač na dekódovanie."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"spravovať dôveryhodné poverenia"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Umožňuje aplikácii inštalovať a odinštalovať certifikáty CA ako dôveryhodné poverenia."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"previazať s nečinnými službami"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Umožňuje aplikácii interakciu s nečinnými službami definovanými aplikáciou."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čítanie alebo zápis do prostriedkov funkcie diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikácii čítať ľubovoľné prostriedky v skupine diag, napr. súbory v priečinku /dev, a zapisovať do nich. Môže dôjsť k ovplyvneniu stability a bezpečnosti systému. Toto nastavenie by mal používať IBA výrobca či operátor na diagnostiku hardvéru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
@@ -554,7 +556,7 @@
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"ovládanie upozornení na aktualizáciu polohy"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Umožňuje aplikácii povoliť alebo zakázať upozornenia s aktualizáciami polohy z rádia. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"prístup k vlastnostiam nahlásenia"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Umožňuje aplikácii čítať a zapisovať vlastnosti odovzdané službou nahlasovania. Bežné aplikácie toto nastavenie nepoužívajú."</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Umožňuje aplikácii čítať a zapisovať vlastnosti nahrané službou nahlasovania. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"zvoliť miniaplikácie"</string>
     <string name="permdesc_bindGadget" msgid="8261326938599049290">"Umožňuje aplikácii povedať systému, ktoré aplikácie môžu používať určité miniaplikácie. Aplikácia s týmto povolením môže iným aplikáciám povoliť prístup k osobným údajom. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"zmeny stavu telefónu"</string>
@@ -1491,7 +1493,7 @@
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bezdrôtový displej"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Pripojenie k zariadeniu"</string>
-    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Odovzdanie obraz. na prehratie v zariad."</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Nahranie obraz. na prehratie v zariad."</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"Prebieha vyhľadávanie zariadení…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Nastavenia"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Odpojiť"</string>
@@ -1505,9 +1507,9 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrytie č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
-    <string name="wifi_display_notification_connecting_title" msgid="2838646471050359706">"Odovzdávanie obrazovky na prehratie"</string>
+    <string name="wifi_display_notification_connecting_title" msgid="2838646471050359706">"Nahrávanie obrazovky na prehratie"</string>
     <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Prebieha pripájanie k obrazovke <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Odovzdávanie obrazovky na prehratie"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Nahrávanie obrazovky na prehratie"</string>
     <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Pripojené k obrazovke <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojiť"</string>
     <string name="kg_emergency_call_label" msgid="684946192523830531">"Tiesňové volanie"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7c0dc63..b56e7b1 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Programu omogoča, da uporabi kateri koli dekodirnik večpredstavnosti za predvajanje."</string>
     <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="7521398788076342815">"vezanje na nedejavne storitve"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Aplikaciji omogoča interakcijo z nedejavnimi storitvami, določenimi z aplikacijami."</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-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 5b5f451..af194ce 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"повезивање са неактивним услугама"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Дозвољава апликацији да остварује интеракцију са неактивним услугама дефинисаним у апликацији."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"читање ресурса у власништву дијагностике и уписивање података у њих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозвољава апликацији да чита и уписује податке у било који ресурс у власништву групе за дијагностиковање, на пример, датотеке у директоријуму /dev. То може да угрози стабилност и безбедност система и треба да је користе САМО произвођач или оператер у сврхе дијагностиковањa хардвера."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index bdd8e76..8b449db 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tillåter att appen använder installerade medieavkodare för att avkoda media för uppspelning."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"hantera betrodda uppgifter"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tillåter att appen installerar och avinstallerar CA-certifikat som betrodda uppgifter."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"knyt till inaktiva tjänster"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Tillåter att appen interagerar med tjänster som har definierats som inaktiva av appen."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"läsa/skriva till resurser som ägs av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillåter att appen läser och skriver till en resurs som ägs av diag-gruppen, till exempel filer i /dev. Detta kan eventuellt påverka systemets stabilitet och säkerhet. Detta bör ENDAST användas av tillverkaren eller operatören för maskinvaruspecifik diagnostik."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivera eller inaktivera appkomponenter"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index d0fcc09..197f3b3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -359,8 +359,8 @@
     <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Huruhusu programu kubadilisha kasi ya uhuishaji kijumla (uhuisho wa haraka zaidi au wa polepole zaidi) wakati wowote."</string>
     <string name="permlab_manageAppTokens" msgid="1286505717050121370">"Dhibiti shuhuda za programu"</string>
     <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Inaruhusu programu kuunda na kudhibiti shuhuda zake, kukwepa mipangilio yao ya kawaida. Haitahitajika kamwe na programu za kawaida."</string>
-    <string name="permlab_freezeScreen" msgid="4708181184441880175">"lemaza skrini"</string>
-    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Inaruhusu programu kulemaza kwa muda skrini kwa ajili ya mpito kamili wa skrinimaombi kwa muda kufungia screen kwa ajili ya mpito full-screen."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"fanya skrini isisonge"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Huruhusu programu kufanya skrini isisonge kwa muda ili kuruhusu kubadilisha hadi skrini nzima."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"bonyeza vitufe na vitufe vya kudhibiti"</string>
     <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Huruhusu programu kuwasilisha matukio yake ya ingizo (mibonyezo ya vitufe, nk.) kwa programu zingine. programu hasidi zinaweza kutumia hii ili kutawala kompyuta kibao."</string>
     <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Inaruhusu programu kuwasilisha matukio yake ya ingizo (mibonyezo ya kitufe, nk.)kwa programu zingine.Programu hasidi zinaweza kutumia hii kutawala simu."</string>
@@ -423,6 +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="7521398788076342815">"funga kwenye huduma zisizofanya kitu"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Huruhusu programu kuwasiliana na huduma zisizofanya kitu zilizobainishwa na programu."</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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a0b2ee4..c0c85d8 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"เชื่อมโยงกับบริการที่ไม่ได้ใช้งาน"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"อนุญาตให้แอปโต้ตอบกับบริการที่แอปพลิเคชันระบุว่าไม่ได้ใช้งาน"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"อ่าน/เขียนไปยังรีซอร์สที่เป็นเจ้าของโดยกลุ่มวินิจฉัย"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังทรัพยากรที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
@@ -1526,7 +1528,7 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"กำลังปลดล็อกซิมการ์ด…"</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"รหัส PIN ไม่ถูกต้อง"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"พิมพ์ PIN ซึ่งเป็นเลข 4 ถึง 8 หลัก"</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"รหัส PUK ต้องเป็นตัวเลข 8 ตัว"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"รหัส PUK ต้องเป็นตัวเลข 8 หลัก"</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"ใส่รหัส PUK ที่ถูกต้องอีกครั้ง การพยายามซ้ำหลายครั้งจะทำให้ซิมการ์ดถูกปิดใช้งานอย่างถาวร"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"รหัส PIN ไม่ตรง"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ลองหลายรูปแบบมากเกินไป"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index af36cee..0b4aa2d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Pinapayagan ang app na gumamit ng anumang naka-install na media decoder upang mag-decode para sa pag-playback."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"mga pinamamahalaang pinagkakatiwalaang kredensyal"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Pinapayagan ang app na mag-install at mag-uninstall ng mga CA certificate bilang mga pinagkakatiwalaang kredensyal."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"sumailalim sa mga idle na serbisyo"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Pinapayagan ang app na makipag-ugnayan sa mga idle na serbisyong partikular sa application."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"magbasa/magsulat sa mga mapagkukunang pag-aari ng diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pinapayagan ang app na magbasa at magsulat sa anumang mapagkukunang pag-aari ng pangkat ng diag; halimbawa, mga file sa /dev. Maaaring potensyal na maapektuhan nito ang katatagan at seguridad ng system. Dapat LAMANG itong gamitin para sa diagnostics na tukoy sa hardware ng tagagawa o operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 99d415a..f583750 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Uygulamaya, oynatma kodunu çözmek için herhangi bir yüklü medya kod çözücüyü kullanma izni verir."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"güvenilen kimlik bilgilerini yönetme"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Uygulamaya, güvenilir kimlik bilgileri olarak CA sertifikaları yükleme veya sertifikaların yüklemelerini kaldırma izni verir."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"boşta kalma hizmetlerine bağlan"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Uygulamaya, uygulama tanımlı boşta kalma hizmetleriyle etkileşim kurma izni verir."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"sahibi tanılama olan kaynakları oku/bunlara yaz"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Uygulamaya, tanılama grubunun sahip olduğu tüm kaynaklara (örneğin /dev içindeki dosyalar) okuma ve yazma izni verir. Bu işlevin sistem kararlılığını ve güvenliğini olumsuz etkileme olasılığı vardır. Üretici veya operatör tarafından YALNIZCA donanıma özgü tanılama için kullanılmalıdır."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index da50f73..a910a97 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"взаємодіяти з неактивними службами"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Дозволяє програмі взаємодіяти з неактивними службами програми."</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-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 0cabb12..eb04530 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Cho phép ứng dụng sử dụng bất kỳ trình giải mã phương tiện nào đã cài đặt nhằm giải mã để phát lại."</string>
     <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="7521398788076342815">"liên kết với dịch vụ không dùng đến"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Cho phép ứng dụng tương tác với dịch vụ không dùng đến được xác định cho ứng 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 507b29b..de5c778 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -423,6 +423,8 @@
     <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="7521398788076342815">"绑定到闲置服务"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"允许该应用与应用定义的闲置服务互动。"</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-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e5441a2..0471d4a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允許應用程式使用任何已安裝的媒體解碼器為播放解碼。"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的憑證"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允許應用程式安裝 CA 憑證為信任的憑證及解除安裝 CA 憑證。"</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"繫結至閒置服務"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"允許應用程式與由應用程式定義的閒置服務進行互動。"</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-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 153f85f..6cbeedf 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允許應用程式使用任何已安裝的媒體解碼器進行解碼以播放影片。"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的憑證"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允許應用程式安裝 CA 憑證 (做為信任的憑證) 及解除安裝 CA 憑證。"</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"繫結至閒置的服務"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"允許應用程式與由應用程式定義的閒置服務進行互動。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀寫 diag 擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取或寫入診斷群組擁有的任何資源,例如 /dev 底下的檔案。這可能會影響系統的穩定性和安全性,因此應由製造商或電信業者操作,且只用在特定硬體診斷。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 2687603..20fe57e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -423,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ivumela uhlelo lokusebenza ukusebenzisa noma isiphi isiqophi semidiya esifakiwe ukuqopha ukudlala."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"phatha ukuqinisekisa okuthenjiwe"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ivumela uhlelo lokusebenza ukuthi lifake liphinde likhiphe izitifiketi ze-CA njengokuqinisekiswa okuthenjiwe."</string>
+    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bophezela kumasevisi angenzi lutho"</string>
+    <string name="permdesc_bindIdleService" msgid="3062157929989572890">"Ivumela uhlelo lokusebenza ukuthi luhlanganyele nohlelo lokusebenza oluchaziwe lwamasevisi angenzi lutho."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"funda/bhalela emithombweni ephethwe idayegi"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ivumela uhlelo lokusebenza ukufunda nokubhala kunoma yimuphi umthombo weqembu ledayegi; ngokwesibonelo, amafayela akwi/dev. Lokhu kungase kuthinte kakhulu ukuba nokuphepha kohlelo. Lokhu kumele kusebenziselwe KUPHELA ukuhlola ihadiwe okucacile ngumkhiqizi noma u-opheretha."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"vumela noma vimbela izingxenye zensiza"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f77d66b..9526e13 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2250,6 +2250,11 @@
              view with a theme override will inherit the themed context. -->
         <attr name="theme" />
 
+        <!-- Specifies that the shared name of the View to be shared with another Activity.
+             When transitioning between Activities, the name links a UI element in the starting
+             Activity to UI element in the called Activity. Names should be unique in the
+             View hierarchy. -->
+        <attr name="sharedElementName" format="string" />
     </declare-styleable>
 
     <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
@@ -2336,6 +2341,14 @@
             <!-- Use the children's optical bounds when laying out this container. -->
             <enum name="opticalBounds" value="1" />
         </attr>
+
+        <!-- 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 more information. -->
+        <attr name="transitionGroup" format="boolean" />
     </declare-styleable>
 
     <!-- A {@link android.view.ViewStub} lets you lazily include other XML layouts
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 5c0baaa..56bb15f 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -82,4 +82,5 @@
   <item type="id" name="action_bar_spinner" />
   <item type="id" name="current_scene" />
   <item type="id" name="scene_layoutid_cache" />
+  <item type="id" name="shared_element_name" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e99b5ba..722f965 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2104,6 +2104,12 @@
   <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="id" name="shared_element_name" />
 
   <public type="style" name="Widget.Holo.FragmentBreadCrumbs" />
   <public type="style" name="Widget.Holo.Light.FragmentBreadCrumbs" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 76fbded..7a654e6 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -363,7 +363,7 @@
         <item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
         <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
         <item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
-        <item name="searchViewSearchIcon">@android:drawable/ic_search</item>
+        <item name="searchViewSearchIcon">@android:drawable/ic_search_api_holo_dark</item>
         <item name="searchViewGoIcon">@android:drawable/ic_go</item>
         <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
         <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index 0518e64..06c6c34 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -23,6 +23,9 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import com.android.frameworks.downloadmanagertests.DownloadManagerBaseTest;
+import com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner;
+
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
@@ -38,14 +41,8 @@
     protected static String LOG_TAG =
             "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
 
-    protected static String DOWNLOAD_500K_FILENAME = "External541kb.apk";
-    protected static long DOWNLOAD_500K_FILESIZE = 570927;
-    protected static String DOWNLOAD_1MB_FILENAME = "External1mb.apk";
-    protected static long DOWNLOAD_1MB_FILESIZE = 1041262;
-    protected static String DOWNLOAD_5MB_FILENAME = "External5mb.apk";
-    protected static long DOWNLOAD_5MB_FILESIZE = 5138700;
-    protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
-    protected static long DOWNLOAD_10MB_FILESIZE = 10258741;
+    protected static final String DOWNLOAD_FILENAME = "External93mb.apk";
+    protected static final long DOWNLOAD_FILESIZE = 95251708;
 
     private static final String FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX = "file";
     private static final String FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION = ".bin";
@@ -126,7 +123,7 @@
      * @throws Exception if unsuccessful
      */
     public void initiateDownload() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
+        String filename = DOWNLOAD_FILENAME;
         mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
         FileOutputStream fileOutput = mContext.openFileOutput(DOWNLOAD_STARTED_FLAG, 0);
         DataOutputStream outputFile = null;
@@ -162,8 +159,8 @@
      * @throws Exception if unsuccessful
      */
     public void verifyFileDownloadSucceeded() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         long dlRequest = -1;
         boolean rebootMarkerValid = false;
         DataInputStream dataInputFile = null;
@@ -223,8 +220,8 @@
      * @throws Exception if unsuccessful
      */
     public void runLargeDownloadOverWiFi() throws Exception {
-        String filename = DOWNLOAD_10MB_FILENAME;
-        long filesize = DOWNLOAD_10MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         long dlRequest = -1;
         doCommonDownloadSetup();
 
@@ -265,8 +262,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleSwitching() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         doCommonDownloadSetup();
 
         String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
@@ -340,8 +337,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleWiFiEnableDisable() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         doCommonDownloadSetup();
 
         String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
@@ -409,8 +406,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleAirplaneModeEnableDisable() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         // make sure WiFi is enabled, and airplane mode is not on
         doCommonDownloadSetup();
 
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 7b9b3fb..bcd4607 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -61,7 +61,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 8, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 4, 2014.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -92,7 +92,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 8, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 4, 2014.
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -133,17 +133,17 @@
 </tr>
 <tr>
 <td>2.0</th>
-<td>93.5%</td>
+<td>92.3%</td>
 </tr>
 <tr>
 <td>3.0</th>
-<td>6.4%</td>
+<td>7.6%</td>
 </tr>
 </table>
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 8, 2014</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 4, 2014</em></p>
 
 
 
@@ -161,7 +161,7 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chf=bg%2Cs%2C00000000&chd=t%3A1.3%2C21.2%2C0.1%2C16.9%2C59.1%2C1.4&chco=c4df9b%2C6fad0c&chs=500x250&cht=p",
+    "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chf=bg%2Cs%2C00000000&chd=t%3A1.3%2C20.0%2C0.1%2C16.1%2C60.7%2C1.8&chco=c4df9b%2C6fad0c",
     "data": [
       {
         "api": 8,
@@ -171,7 +171,7 @@
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "21.2"
+        "perc": "20.0"
       },
       {
         "api": 13,
@@ -181,27 +181,27 @@
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "16.9"
+        "perc": "16.1"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "35.9"
+        "perc": "35.5"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "15.4"
+        "perc": "16.3"
       },
       {
         "api": 18,
         "name": "Jelly Bean",
-        "perc": "7.8"
+        "perc": "8.9"
       },
       {
         "api": 19,
         "name": "KitKat",
-        "perc": "1.4"
+        "perc": "1.8"
       }
     ]
   }
@@ -217,30 +217,30 @@
     "data": {
       "Large": {
         "hdpi": "0.6",
-        "ldpi": "0.9",
-        "mdpi": "4.5",
-        "tvdpi": "1.7",
-        "xhdpi": "0.7"
+        "ldpi": "0.8",
+        "mdpi": "4.4",
+        "tvdpi": "1.6",
+        "xhdpi": "0.6"
       },
       "Normal": {
-        "hdpi": "33.0",
+        "hdpi": "33.3",
         "ldpi": "0.1",
-        "mdpi": "14.2",
-        "xhdpi": "20.1",
-        "xxhdpi": "10.6"
+        "mdpi": "13.9",
+        "xhdpi": "20.2",
+        "xxhdpi": "11.3"
       },
       "Small": {
-        "ldpi": "8.2"
+        "ldpi": "8.1"
       },
       "Xlarge": {
-        "hdpi": "0.4",
+        "hdpi": "0.3",
         "ldpi": "0.1",
-        "mdpi": "4.7",
+        "mdpi": "4.5",
         "xhdpi": "0.2"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A9.4%2C23.5%2C1.7%2C34.0%2C21.0%2C10.6&chco=c4df9b%2C6fad0c&chs=400x250&cht=p",
-    "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A5.4%2C8.5%2C78.0%2C8.2&chco=c4df9b%2C6fad0c&chs=400x250&cht=p"
+    "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A9.1%2C22.8%2C1.6%2C34.3%2C21.0%2C11.3&chco=c4df9b%2C6fad0c",
+    "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A5.1%2C8.0%2C78.9%2C8.1&chco=c4df9b%2C6fad0c"
   }
 ];
 
diff --git a/docs/html/google/play-services/setup.jd b/docs/html/google/play-services/setup.jd
index bf7fbe2..fb5daf8 100644
--- a/docs/html/google/play-services/setup.jd
+++ b/docs/html/google/play-services/setup.jd
@@ -92,7 +92,10 @@
 <p><b>Using Android Studio:</b></p>
 
 <ol>
-  <li>Open the <code>build.gradle</code> file inside your application directory.</li>
+  <li>Open the <code>build.gradle</code> file inside your application module directory. 
+      <p class="note"><strong>Note:</strong> Android Studio projects contain a top-level 
+      <code>build.gradle</code> file and a <code>build.gradle</code> file for each module. 
+      Be sure to edit the file for your application module.</p></li>
   <li>Add a new build rule under <code>dependencies</code> for the latest version of
 <code>play-services</code>. For example:
 <pre class="no-pretty-print">
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index c62510b..297a2dc 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -56,7 +56,9 @@
 RenderScript kernel language used in this script. Currently, 1 is the only valid value.</li>
 
 <li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that
-declares the package name of the Java classes reflected from this script.</li>
+declares the package name of the Java classes reflected from this script.
+Note that your .rs file must be part of your application package, and not in a
+library project.</li>
 
 <li>Some number of invokable functions. An invokable function is a single-threaded RenderScript
 function that you can call from your Java code with arbitrary arguments. These are often useful for
@@ -308,4 +310,4 @@
 <li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed
 with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context
 object to be garbage collected. This will cause any further use of any object belonging to that
-context to throw an exception.</li> </ol>
\ No newline at end of file
+context to throw an exception.</li> </ol>
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 1850123..f980042 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -27,6 +27,7 @@
   </li>
   <li><a href="#logcat">Enabling logcat logging</a></li>
   <li><a href="#stopping">Stopping the adb server</a></li>
+  <li><a href="#wireless">Wireless usage</a></li>
 </ol>
 
 </div>
@@ -1342,3 +1343,100 @@
 You can then restart the server by issuing any other adb command. </p>
 
 
+<h2 id="wireless">Wireless usage</h2>
+
+<p>
+adb is usually used over USB.  However, it is also possible to use over
+Wi-Fi, as described here.
+</p>
+
+<ol>
+
+<li>
+Connect Android device and adb host computer
+to a common Wi-Fi network accessible to both.
+We have found that not all access points
+are suitable; you may need to use an access point
+whose firewall is configured properly to support adb.
+</li>
+
+<li>
+Connect the device with USB cable to host.
+</li>
+
+<li>
+Make sure adb is running in USB mode on host.
+<pre>
+$ adb usb
+restarting in USB mode
+</pre>
+</li>
+
+<li>
+Connect to the device over USB.
+<pre>
+$ adb devices
+List of devices attached
+######## device
+</pre>
+</li>
+
+<li>
+Restart host adb in tcpip mode.
+<pre>
+$ adb tcpip 5555
+restarting in TCP mode port: 5555
+</pre>
+</li>
+
+<li>
+Find out the IP address of the Android device:
+Settings -> About tablet -> Status -> IP address.
+Remember the IP address, of the form <code>#.#.#.#</code>.
+</li>
+
+<li>
+Connect adb host to device:
+<pre>
+$ adb connect #.#.#.#
+connected to #.#.#.#:5555
+</pre>
+</li>
+
+<li>
+Remove USB cable from device, and confirm you can still access device:
+<pre>
+$ adb devices
+List of devices attached
+#.#.#.#:5555 device
+</pre>
+
+</ol>
+
+<p>
+You're now good to go!
+</p>
+
+<p>
+If the adb connection is ever lost:
+</p>
+
+<ol>
+
+<li>
+Make sure that your host is still connected to the same Wi-Fi network your Android device is.
+</li>
+
+<li>
+Reconnect by executing the "adb connect" step again.
+</li>
+
+<li>
+Or if that doesn't work, reset your adb host:
+<pre>
+adb kill-server
+</pre>
+and then start over from the beginning.
+</li>
+
+</ol>
diff --git a/docs/html/tools/samples/index.jd b/docs/html/tools/samples/index.jd
deleted file mode 100644
index a0d11e9..0000000
--- a/docs/html/tools/samples/index.jd
+++ /dev/null
@@ -1,32 +0,0 @@
-page.title=Samples
-page.tags=example,code
-@jd:body
-
-<p>To help you understand some fundamental Android APIs and coding practices, a variety of sample
-code is available from the Android SDK Manager. Each version of the Android platform available
-from the SDK Manager offers its own set of sample apps.</p>
-
-<p>To download the samples:</p>
-<ol>
-  <li>Launch the Android SDK Manager.
-    <ul>
-      <li>On Windows, double-click the SDK Manager.exe file at the root of the Android SDK
-directory.</li>
-      <li>On Mac or Linux, open a terminal to the {@code tools/} directory in the
-Android SDK, then execute {@code android sdk}.</ul>
-  </li>
-  <li>Expand the list of packages for the latest Android platform.</li>
-  <li>Select and download <em>Samples for SDK</em>.</li>
-</ol>
-
-<p>When the download is complete, you can find the source code for all samples at this location:</p>
-
-<p style="margin-left:2em">
-<code>&lt;sdk&gt;/samples/android-&lt;version>/</code>
-</p>
-
-<p>The {@code &lt;version>} number corresponds to the platform's
-  <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level</a>.</p>
-
-<p>You can easily create new Android projects with the downloaded samples, modify them
-if you'd like, and then run them on an emulator or device.</p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 3e6b6d4..a8424e6 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -240,12 +240,6 @@
 
 
   <li class="nav-section">
-    <div class="nav-section-header empty"><a href="<?cs var:toroot
-?>tools/samples/index.html"><span class="en">Samples</span></a></div>
-  </li>
-
-
-  <li class="nav-section">
     <div class="nav-section-header">
     <a href="<?cs var:toroot ?>tools/adk/index.html">
       <span class="en">ADK</span></a>
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index aec3a4b..630dc2e 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -31,13 +31,14 @@
 import java.io.IOException;
 
 /**
- * <p>A Drawable that can rotate another Drawable based on the current level
- * value. The start and end angles of rotation can be controlled to map any
- * circular arc to the level values range.</p>
- *
- * <p>It can be defined in an XML file with the <code>&lt;rotate></code> element. For more
- * information, see the guide to <a
- * href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+ * <p>
+ * A Drawable that can rotate another Drawable based on the current level value.
+ * The start and end angles of rotation can be controlled to map any circular
+ * arc to the level values range.
+ * <p>
+ * It can be defined in an XML file with the <code>&lt;rotate&gt;</code> element.
+ * For more information, see the guide to
+ * <a href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.
  *
  * @attr ref android.R.styleable#RotateDrawable_visible
  * @attr ref android.R.styleable#RotateDrawable_fromDegrees
@@ -49,20 +50,21 @@
 public class RotateDrawable extends Drawable implements Drawable.Callback {
     private static final float MAX_LEVEL = 10000.0f;
 
-    private RotateState mState;
+    private final RotateState mState;
+
     private boolean mMutated;
 
     /**
-     * <p>Create a new rotating drawable with an empty state.</p>
+     * Create a new rotating drawable with an empty state.
      */
     public RotateDrawable() {
         this(null, null);
     }
 
     /**
-     * <p>Create a new rotating drawable with the specified state. A copy of
+     * Create a new rotating drawable with the specified state. A copy of
      * this state is used as the internal state for the newly created
-     * drawable.</p>
+     * drawable.
      *
      * @param rotateState the state for this drawable
      */
@@ -70,28 +72,42 @@
         mState = new RotateState(rotateState, this, res);
     }
 
+    @Override
     public void draw(Canvas canvas) {
-        int saveCount = canvas.save();
-
-        Rect bounds = mState.mDrawable.getBounds();
-
-        int w = bounds.right - bounds.left;
-        int h = bounds.bottom - bounds.top;
-
         final RotateState st = mState;
-        
-        float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
-        float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
+        final Drawable d = st.mDrawable;
+        final Rect bounds = d.getBounds();
+        final int w = bounds.right - bounds.left;
+        final int h = bounds.bottom - bounds.top;
+        final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
+        final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
 
+        final int saveCount = canvas.save();
         canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
-
-        st.mDrawable.draw(canvas);
-
+        d.draw(canvas);
         canvas.restoreToCount(saveCount);
     }
 
     /**
-     * Returns the drawable rotated by this RotateDrawable.
+     * Sets the drawable rotated by this RotateDrawable.
+     *
+     * @param drawable The drawable to rotate
+     */
+    public void setDrawable(Drawable drawable) {
+        final Drawable oldDrawable = mState.mDrawable;
+        if (oldDrawable != drawable) {
+            if (oldDrawable != null) {
+                oldDrawable.setCallback(null);
+            }
+            mState.mDrawable = drawable;
+            if (drawable != null) {
+                drawable.setCallback(this);
+            }
+        }
+    }
+
+    /**
+     * @return The drawable rotated by this RotateDrawable
      */
     public Drawable getDrawable() {
         return mState.mDrawable;
@@ -103,7 +119,8 @@
                 | mState.mChangingConfigurations
                 | mState.mDrawable.getChangingConfigurations();
     }
-    
+
+    @Override
     public void setAlpha(int alpha) {
         mState.mDrawable.setAlpha(alpha);
     }
@@ -113,14 +130,149 @@
         return mState.mDrawable.getAlpha();
     }
 
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mState.mDrawable.setColorFilter(cf);
     }
 
+    @Override
     public int getOpacity() {
         return mState.mDrawable.getOpacity();
     }
 
+    /**
+     * Sets the start angle for rotation.
+     *
+     * @param fromDegrees Starting angle in degrees
+     */
+    public void setFromDegrees(float fromDegrees) {
+        if (mState.mFromDegrees != fromDegrees) {
+            mState.mFromDegrees = fromDegrees;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return The starting angle for rotation in degrees
+     */
+    public float getFromDegrees() {
+        return mState.mFromDegrees;
+    }
+
+    /**
+     * Sets the end angle for rotation.
+     *
+     * @param toDegrees Ending angle in degrees
+     */
+    public void setToDegrees(float toDegrees) {
+        if (mState.mToDegrees != toDegrees) {
+            mState.mToDegrees = toDegrees;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return The ending angle for rotation in degrees
+     */
+    public float getToDegrees() {
+        return mState.mToDegrees;
+    }
+
+    /**
+     * Sets the X position around which the drawable is rotated.
+     *
+     * @param pivotX X position around which to rotate. If the X pivot is
+     *            relative, the position represents a fraction of the drawable
+     *            width. Otherwise, the position represents an absolute value in
+     *            pixels.
+     * @see #setPivotXRelative(boolean)
+     */
+    public void setPivotX(float pivotX) {
+        if (mState.mPivotX == pivotX) {
+            mState.mPivotX = pivotX;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return X position around which to rotate
+     * @see #setPivotX(float)
+     */
+    public float getPivotX() {
+        return mState.mPivotX;
+    }
+
+    /**
+     * Sets whether the X pivot value represents a fraction of the drawable
+     * width or an absolute value in pixels.
+     *
+     * @param relative True if the X pivot represents a fraction of the drawable
+     *            width, or false if it represents an absolute value in pixels
+     */
+    public void setPivotXRelative(boolean relative) {
+        if (mState.mPivotXRel == relative) {
+            mState.mPivotXRel = relative;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return True if the X pivot represents a fraction of the drawable width,
+     *         or false if it represents an absolute value in pixels
+     * @see #setPivotXRelative(boolean)
+     */
+    public boolean isPivotXRelative() {
+        return mState.mPivotXRel;
+    }
+
+    /**
+     * Sets the Y position around which the drawable is rotated.
+     *
+     * @param pivotY Y position around which to rotate. If the Y pivot is
+     *            relative, the position represents a fraction of the drawable
+     *            height. Otherwise, the position represents an absolute value
+     *            in pixels.
+     * @see #setPivotYRelative(boolean)
+     */
+    public void setPivotY(float pivotY) {
+        if (mState.mPivotY == pivotY) {
+            mState.mPivotY = pivotY;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return Y position around which to rotate
+     * @see #setPivotY(float)
+     */
+    public float getPivotY() {
+        return mState.mPivotY;
+    }
+
+    /**
+     * Sets whether the Y pivot value represents a fraction of the drawable
+     * height or an absolute value in pixels.
+     *
+     * @param relative True if the Y pivot represents a fraction of the drawable
+     *            height, or false if it represents an absolute value in pixels
+     */
+    public void setPivotYRelative(boolean relative) {
+        if (mState.mPivotYRel == relative) {
+            mState.mPivotYRel = relative;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return True if the Y pivot represents a fraction of the drawable height,
+     *         or false if it represents an absolute value in pixels
+     * @see #setPivotYRelative(boolean)
+     */
+    public boolean isPivotYRelative() {
+        return mState.mPivotYRel;
+    }
+
+    @Override
     public void invalidateDrawable(Drawable who) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -128,6 +280,7 @@
         }
     }
 
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -135,6 +288,7 @@
         }
     }
 
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -157,10 +311,10 @@
     public boolean isStateful() {
         return mState.mDrawable.isStateful();
     }
-    
+
     @Override
     protected boolean onStateChange(int[] state) {
-        boolean changed = mState.mDrawable.setState(state);
+        final boolean changed = mState.mDrawable.setState(state);
         onBoundsChange(getBounds());
         return changed;
     }
@@ -172,7 +326,7 @@
 
         mState.mCurrentDegrees = mState.mFromDegrees +
                 (mState.mToDegrees - mState.mFromDegrees) *
-                        ((float) level / MAX_LEVEL);
+                        (level / MAX_LEVEL);
 
         invalidateSelf();
         return true;
@@ -206,16 +360,15 @@
     @Override
     public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
             throws XmlPullParserException, IOException {
-
-        TypedArray a = r.obtainAttributes(attrs,
+        final TypedArray a = r.obtainAttributes(attrs,
                 com.android.internal.R.styleable.RotateDrawable);
 
         super.inflateWithAttributes(r, parser, a,
                 com.android.internal.R.styleable.RotateDrawable_visible);
-        
+
         TypedValue tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotX);
-        boolean pivotXRel;
-        float pivotX;
+        final boolean pivotXRel;
+        final float pivotX;
         if (tv == null) {
             pivotXRel = true;
             pivotX = 0.5f;
@@ -223,10 +376,10 @@
             pivotXRel = tv.type == TypedValue.TYPE_FRACTION;
             pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
         }
-        
+
         tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotY);
-        boolean pivotYRel;
-        float pivotY;
+        final boolean pivotYRel;
+        final float pivotY;
         if (tv == null) {
             pivotYRel = true;
             pivotY = 0.5f;
@@ -235,12 +388,12 @@
             pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
         }
 
-        float fromDegrees = a.getFloat(
+        final float fromDegrees = a.getFloat(
                 com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
-        float toDegrees = a.getFloat(
+        final float toDegrees = a.getFloat(
                 com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);
 
-        int res = a.getResourceId(
+        final int res = a.getResourceId(
                 com.android.internal.R.styleable.RotateDrawable_drawable, 0);
         Drawable drawable = null;
         if (res > 0) {
@@ -248,8 +401,8 @@
         }
 
         a.recycle();
-        
-        int outerDepth = parser.getDepth();
+
+        final int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
                (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -268,13 +421,15 @@
             Log.w("drawable", "No drawable specified for <rotate>");
         }
 
-        mState.mDrawable = drawable;
-        mState.mPivotXRel = pivotXRel;
-        mState.mPivotX = pivotX;
-        mState.mPivotYRel = pivotYRel;
-        mState.mPivotY = pivotY;
-        mState.mFromDegrees = mState.mCurrentDegrees = fromDegrees;
-        mState.mToDegrees = toDegrees;
+        final RotateState st = mState;
+        st.mDrawable = drawable;
+        st.mPivotXRel = pivotXRel;
+        st.mPivotX = pivotX;
+        st.mPivotYRel = pivotYRel;
+        st.mPivotY = pivotY;
+        st.mFromDegrees = fromDegrees;
+        st.mCurrentDegrees = fromDegrees;
+        st.mToDegrees = toDegrees;
 
         if (drawable != null) {
             drawable.setCallback(this);
@@ -291,15 +446,15 @@
     }
 
     /**
-     * <p>Represents the state of a rotation for a given drawable. The same
+     * Represents the state of a rotation for a given drawable. The same
      * rotate drawable can be invoked with different states to drive several
-     * rotations at the same time.</p>
+     * rotations at the same time.
      */
     final static class RotateState extends Drawable.ConstantState {
         Drawable mDrawable;
 
         int mChangingConfigurations;
-        
+
         boolean mPivotXRel;
         float mPivotX;
         boolean mPivotYRel;
@@ -311,7 +466,7 @@
         float mCurrentDegrees;
 
         private boolean mCanConstantState;
-        private boolean mCheckedConstantState;        
+        private boolean mCheckedConstantState;
 
         public RotateState(RotateState source, RotateDrawable owner, Resources res) {
             if (source != null) {
@@ -336,12 +491,12 @@
         public Drawable newDrawable() {
             return new RotateDrawable(this, null);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new RotateDrawable(this, res);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
diff --git a/media/java/android/media/IMediaHTTPConnection.aidl b/media/java/android/media/IMediaHTTPConnection.aidl
new file mode 100644
index 0000000..300211b
--- /dev/null
+++ b/media/java/android/media/IMediaHTTPConnection.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 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.
+ * 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.media;
+
+import android.os.IBinder;
+
+/** MUST STAY IN SYNC WITH NATIVE CODE at libmedia/IMediaHTTPConnection.{cpp,h} */
+
+/** @hide */
+interface IMediaHTTPConnection
+{
+    IBinder connect(in String uri, in String headers);
+    void disconnect();
+
+    int readAt(long offset, int size);
+    long getSize();
+    String getMIMEType();
+}
+
diff --git a/media/java/android/media/IMediaHTTPService.aidl b/media/java/android/media/IMediaHTTPService.aidl
new file mode 100644
index 0000000..8aaf6b3
--- /dev/null
+++ b/media/java/android/media/IMediaHTTPService.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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.
+ * 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.media;
+
+import android.media.IMediaHTTPConnection;
+
+/** MUST STAY IN SYNC WITH NATIVE CODE at libmedia/IMediaHTTPService.{cpp,h} */
+
+/** @hide */
+interface IMediaHTTPService
+{
+    IMediaHTTPConnection makeHTTPConnection();
+}
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index c3e5035..f2753ee 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -21,7 +21,9 @@
 import android.content.res.AssetFileDescriptor;
 import android.media.MediaCodec;
 import android.media.MediaFormat;
+import android.media.MediaHTTPService;
 import android.net.Uri;
+import android.os.IBinder;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -137,11 +139,19 @@
                 ++i;
             }
         }
-        setDataSource(path, keys, values);
+
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                keys,
+                values);
     }
 
-    private native final void setDataSource(
-            String path, String[] keys, String[] values) throws IOException;
+    private native final void nativeSetDataSource(
+            IBinder httpServiceBinder,
+            String path,
+            String[] keys,
+            String[] values) throws IOException;
 
     /**
      * Sets the data source (file-path or http URL) to use.
@@ -156,7 +166,11 @@
      * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
      */
     public final void setDataSource(String path) throws IOException {
-        setDataSource(path, null, null);
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                null,
+                null);
     }
 
     /**
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
new file mode 100644
index 0000000..2732fbc
--- /dev/null
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 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.
+ * 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.media;
+
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.StrictMode;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Map;
+
+/** @hide */
+public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
+    private static final String TAG = "MediaHTTPConnection";
+    private static final boolean VERBOSE = false;
+
+    private long mCurrentOffset = -1;
+    private URL mURL = null;
+    private Map<String, String> mHeaders = null;
+    private HttpURLConnection mConnection = null;
+    private long mTotalSize = -1;
+    private InputStream mInputStream = null;
+
+    public MediaHTTPConnection() {
+        if (CookieHandler.getDefault() == null) {
+            CookieHandler.setDefault(new CookieManager());
+        }
+
+        native_setup();
+    }
+
+    public IBinder connect(String uri, String headers) {
+        if (VERBOSE) {
+            Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
+        }
+
+        try {
+            disconnect();
+            mURL = new URL(uri);
+            mHeaders = convertHeaderStringToMap(headers);
+        } catch (MalformedURLException e) {
+            return null;
+        }
+
+        return native_getIMemory();
+    }
+
+    private Map<String, String> convertHeaderStringToMap(String headers) {
+        HashMap<String, String> map = new HashMap<String, String>();
+
+        String[] pairs = headers.split("\r\n");
+        for (String pair : pairs) {
+            int colonPos = pair.indexOf(":");
+            if (colonPos >= 0) {
+                String key = pair.substring(0, colonPos);
+                String val = pair.substring(colonPos + 1);
+
+                map.put(key, val);
+            }
+        }
+
+        return map;
+    }
+
+    public void disconnect() {
+        teardownConnection();
+        mHeaders = null;
+        mURL = null;
+    }
+
+    private void teardownConnection() {
+        if (mConnection != null) {
+            mInputStream = null;
+
+            mConnection.disconnect();
+            mConnection = null;
+
+            mCurrentOffset = -1;
+        }
+    }
+
+    private void seekTo(long offset) throws IOException {
+        teardownConnection();
+
+        try {
+            mConnection = (HttpURLConnection)mURL.openConnection();
+
+            if (mHeaders != null) {
+                for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
+                    mConnection.setRequestProperty(
+                            entry.getKey(), entry.getValue());
+                }
+            }
+
+            if (offset > 0) {
+                mConnection.setRequestProperty(
+                        "Range", "bytes=" + offset + "-");
+            }
+
+            if (mConnection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
+                // Partial content, we cannot just use getContentLength
+                // because what we want is not just the length of the range
+                // returned but the size of the full content if available.
+
+                String contentRange =
+                    mConnection.getHeaderField("Content-Range");
+
+                mTotalSize = -1;
+                if (contentRange != null) {
+                    // format is "bytes xxx-yyy/zzz
+                    // where "zzz" is the total number of bytes of the
+                    // content or '*' if unknown.
+
+                    int lastSlashPos = contentRange.lastIndexOf('/');
+                    if (lastSlashPos >= 0) {
+                        String total =
+                            contentRange.substring(lastSlashPos + 1);
+
+                        try {
+                            mTotalSize = Long.parseLong(total);
+                        } catch (NumberFormatException e) {
+                        }
+                    }
+                }
+            } else if (mConnection.getResponseCode()
+                    != HttpURLConnection.HTTP_OK) {
+                throw new IOException();
+            } else {
+                mTotalSize = mConnection.getContentLength();
+            }
+
+            if (offset > 0
+                    && mConnection.getResponseCode()
+                            != HttpURLConnection.HTTP_PARTIAL) {
+                // Some servers simply ignore "Range" requests and serve
+                // data from the start of the content.
+                throw new IOException();
+            }
+
+            mInputStream =
+                new BufferedInputStream(mConnection.getInputStream());
+
+            mCurrentOffset = offset;
+        } catch (IOException e) {
+            mTotalSize = -1;
+            mInputStream = null;
+            mConnection = null;
+            mCurrentOffset = -1;
+
+            throw e;
+        }
+    }
+
+    public int readAt(long offset, int size) {
+        return native_readAt(offset, size);
+    }
+
+    private int readAt(long offset, byte[] data, int size) {
+        StrictMode.ThreadPolicy policy =
+            new StrictMode.ThreadPolicy.Builder().permitAll().build();
+
+        StrictMode.setThreadPolicy(policy);
+
+        try {
+            if (offset != mCurrentOffset) {
+                seekTo(offset);
+            }
+
+            int n = mInputStream.read(data, 0, size);
+
+            if (n == -1) {
+                // InputStream signals EOS using a -1 result, our semantics
+                // are to return a 0-length read.
+                n = 0;
+            }
+
+            mCurrentOffset += n;
+
+            if (VERBOSE) {
+                Log.d(TAG, "readAt " + offset + " / " + size + " => " + n);
+            }
+
+            return n;
+        } catch (IOException e) {
+            if (VERBOSE) {
+                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
+            }
+            return -1;
+        } catch (Exception e) {
+            if (VERBOSE) {
+                Log.d(TAG, "unknown exception " + e);
+                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
+            }
+            return -1;
+        }
+    }
+
+    public long getSize() {
+        if (mConnection == null) {
+            try {
+                seekTo(0);
+            } catch (IOException e) {
+                return -1;
+            }
+        }
+
+        return mTotalSize;
+    }
+
+    public String getMIMEType() {
+        if (mConnection == null) {
+            try {
+                seekTo(0);
+            } catch (IOException e) {
+                return "application/octet-stream";
+            }
+        }
+
+        return mConnection.getContentType();
+    }
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    private static native final void native_init();
+    private native final void native_setup();
+    private native final void native_finalize();
+
+    private native final IBinder native_getIMemory();
+    private native final int native_readAt(long offset, int size);
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private int mNativeContext;
+}
diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java
new file mode 100644
index 0000000..3b4703d
--- /dev/null
+++ b/media/java/android/media/MediaHTTPService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 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.
+ * 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.media;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+
+/** @hide */
+public class MediaHTTPService extends IMediaHTTPService.Stub {
+    private static final String TAG = "MediaHTTPService";
+
+    public MediaHTTPService() {
+    }
+
+    public IMediaHTTPConnection makeHTTPConnection() {
+        return new MediaHTTPConnection();
+    }
+
+    /* package private */static IBinder createHttpServiceBinderIfNecessary(
+            String path) {
+        if (path.startsWith("http://")
+                || path.startsWith("https://")
+                || path.startsWith("widevine://")) {
+            return (new MediaHTTPService()).asBinder();
+        }
+
+        return null;
+    }
+}
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index db27d09..9a69c06 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -21,6 +21,7 @@
 import android.content.res.AssetFileDescriptor;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.IBinder;
 
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -100,11 +101,16 @@
             values[i] = entry.getValue();
             ++i;
         }
-        _setDataSource(uri, keys, values);
+
+        _setDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(uri),
+                uri,
+                keys,
+                values);
     }
 
     private native void _setDataSource(
-        String uri, String[] keys, String[] values)
+        IBinder httpServiceBinder, String uri, String[] keys, String[] values)
         throws IllegalArgumentException;
 
     /**
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 3cceb03..7c3c197 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
@@ -989,8 +990,18 @@
         }
     }
 
-    private native void _setDataSource(
+    private void _setDataSource(
         String path, String[] keys, String[] values)
+        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                keys,
+                values);
+    }
+
+    private native void nativeSetDataSource(
+        IBinder httpServiceBinder, String path, String[] keys, String[] values)
         throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
 
     /**
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 53835e2..01485b8 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -55,6 +55,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Locale;
@@ -1400,27 +1401,60 @@
         return false;
     }
 
-    public static boolean isNoMediaPath(String path) {
-        if (path == null) return false;
+    private static HashMap<String,String> mNoMediaPaths = new HashMap<String,String>();
+    private static HashMap<String,String> mMediaPaths = new HashMap<String,String>();
 
-        // return true if file or any parent directory has name starting with a dot
-        if (path.indexOf("/.") >= 0) return true;
-
-        // now check to see if any parent directories have a ".nomedia" file
-        // start from 1 so we don't bother checking in the root directory
-        int offset = 1;
-        while (offset >= 0) {
-            int slashIndex = path.indexOf('/', offset);
-            if (slashIndex > offset) {
-                slashIndex++; // move past slash
-                File file = new File(path.substring(0, slashIndex) + ".nomedia");
-                if (file.exists()) {
-                    // we have a .nomedia in one of the parent directories
-                    return true;
-                }
+    /* MediaProvider calls this when a .nomedia file is added or removed */
+    public static void clearMediaPathCache(boolean clearMediaPaths, boolean clearNoMediaPaths) {
+        synchronized (MediaScanner.class) {
+            if (clearMediaPaths) {
+                mMediaPaths.clear();
             }
-            offset = slashIndex;
+            if (clearNoMediaPaths) {
+                mNoMediaPaths.clear();
+            }
         }
+    }
+
+    public static boolean isNoMediaPath(String path) {
+        if (path == null) {
+            return false;
+        }
+        // return true if file or any parent directory has name starting with a dot
+        if (path.indexOf("/.") >= 0) {
+            return true;
+        }
+
+        int firstSlash = path.lastIndexOf('/');
+        if (firstSlash == 0) {
+            return false;
+        }
+        String parent = path.substring(0,  firstSlash);
+
+        synchronized (MediaScanner.class) {
+            if (mNoMediaPaths.containsKey(parent)) {
+                return true;
+            } else if (!mMediaPaths.containsKey(parent)) {
+                // check to see if any parent directories have a ".nomedia" file
+                // start from 1 so we don't bother checking in the root directory
+                int offset = 1;
+                while (offset >= 0) {
+                    int slashIndex = path.indexOf('/', offset);
+                    if (slashIndex > offset) {
+                        slashIndex++; // move past slash
+                        File file = new File(path.substring(0, slashIndex) + ".nomedia");
+                        if (file.exists()) {
+                            // we have a .nomedia in one of the parent directories
+                            mNoMediaPaths.put(parent, "");
+                            return true;
+                        }
+                    }
+                    offset = slashIndex;
+                }
+                mMediaPaths.put(parent, "");
+            }
+        }
+
         return isNoMediaFile(path);
     }
 
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index dea971e..51fccd4 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -8,6 +8,7 @@
     android_media_MediaCodecList.cpp \
     android_media_MediaDrm.cpp \
     android_media_MediaExtractor.cpp \
+    android_media_MediaHTTPConnection.cpp \
     android_media_MediaMuxer.cpp \
     android_media_MediaPlayer.cpp \
     android_media_MediaRecorder.cpp \
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 705de88..d3a8b22 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -26,6 +26,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 
+#include <media/IMediaHTTPService.h>
 #include <media/hardware/CryptoAPI.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -35,6 +36,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/NuMediaExtractor.h>
 
+#include "android_util_Binder.h"
+
 namespace android {
 
 struct fields_t {
@@ -135,8 +138,10 @@
 }
 
 status_t JMediaExtractor::setDataSource(
-        const char *path, const KeyedVector<String8, String8> *headers) {
-    return mImpl->setDataSource(path, headers);
+        const sp<IMediaHTTPService> &httpService,
+        const char *path,
+        const KeyedVector<String8, String8> *headers) {
+    return mImpl->setDataSource(httpService, path, headers);
 }
 
 status_t JMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
@@ -661,7 +666,10 @@
 
 static void android_media_MediaExtractor_setDataSource(
         JNIEnv *env, jobject thiz,
-        jstring pathObj, jobjectArray keysArray, jobjectArray valuesArray) {
+        jobject httpServiceBinderObj,
+        jstring pathObj,
+        jobjectArray keysArray,
+        jobjectArray valuesArray) {
     sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
 
     if (extractor == NULL) {
@@ -686,7 +694,13 @@
         return;
     }
 
-    status_t err = extractor->setDataSource(path, &headers);
+    sp<IMediaHTTPService> httpService;
+    if (httpServiceBinderObj != NULL) {
+        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
+        httpService = interface_cast<IMediaHTTPService>(binder);
+    }
+
+    status_t err = extractor->setDataSource(httpService, path, &headers);
 
     env->ReleaseStringUTFChars(pathObj, path);
     path = NULL;
@@ -839,8 +853,9 @@
     { "native_finalize", "()V",
       (void *)android_media_MediaExtractor_native_finalize },
 
-    { "setDataSource", "(Ljava/lang/String;[Ljava/lang/String;"
-                       "[Ljava/lang/String;)V",
+    { "nativeSetDataSource",
+        "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
+        "[Ljava/lang/String;)V",
       (void *)android_media_MediaExtractor_setDataSource },
 
     { "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
index ccbad8c..e5a0c16e 100644
--- a/media/jni/android_media_MediaExtractor.h
+++ b/media/jni/android_media_MediaExtractor.h
@@ -29,6 +29,7 @@
 
 namespace android {
 
+struct IMediaHTTPService;
 struct MetaData;
 struct NuMediaExtractor;
 
@@ -36,6 +37,7 @@
     JMediaExtractor(JNIEnv *env, jobject thiz);
 
     status_t setDataSource(
+            const sp<IMediaHTTPService> &httpService,
             const char *path,
             const KeyedVector<String8, String8> *headers);
 
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
new file mode 100644
index 0000000..c48af11
--- /dev/null
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaHTTPConnection-JNI"
+#include <utils/Log.h>
+
+#include <binder/MemoryDealer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "android_media_MediaHTTPConnection.h"
+#include "android_util_Binder.h"
+
+#include "android_runtime/AndroidRuntime.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+namespace android {
+
+JMediaHTTPConnection::JMediaHTTPConnection(JNIEnv *env, jobject thiz)
+    : mClass(NULL),
+      mObject(NULL),
+      mByteArrayObj(NULL) {
+    jclass clazz = env->GetObjectClass(thiz);
+    CHECK(clazz != NULL);
+
+    mClass = (jclass)env->NewGlobalRef(clazz);
+    mObject = env->NewWeakGlobalRef(thiz);
+
+    mDealer = new MemoryDealer(kBufferSize, "MediaHTTPConnection");
+    mMemory = mDealer->allocate(kBufferSize);
+
+    ScopedLocalRef<jbyteArray> tmp(
+            env, env->NewByteArray(JMediaHTTPConnection::kBufferSize));
+
+    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
+}
+
+JMediaHTTPConnection::~JMediaHTTPConnection() {
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+    env->DeleteGlobalRef(mByteArrayObj);
+    mByteArrayObj = NULL;
+    env->DeleteWeakGlobalRef(mObject);
+    mObject = NULL;
+    env->DeleteGlobalRef(mClass);
+    mClass = NULL;
+}
+
+sp<IMemory> JMediaHTTPConnection::getIMemory() {
+    return mMemory;
+}
+
+jbyteArray JMediaHTTPConnection::getByteArrayObj() {
+    return mByteArrayObj;
+}
+
+}  // namespace android
+
+using namespace android;
+
+struct fields_t {
+    jfieldID context;
+
+    jmethodID readAtMethodID;
+};
+
+static fields_t gFields;
+
+static sp<JMediaHTTPConnection> setObject(
+        JNIEnv *env, jobject thiz, const sp<JMediaHTTPConnection> &conn) {
+    sp<JMediaHTTPConnection> old =
+        (JMediaHTTPConnection *)env->GetIntField(thiz, gFields.context);
+
+    if (conn != NULL) {
+        conn->incStrong(thiz);
+    }
+    if (old != NULL) {
+        old->decStrong(thiz);
+    }
+    env->SetIntField(thiz, gFields.context, (int)conn.get());
+
+    return old;
+}
+
+static sp<JMediaHTTPConnection> getObject(JNIEnv *env, jobject thiz) {
+    return (JMediaHTTPConnection *)env->GetIntField(thiz, gFields.context);
+}
+
+static void android_media_MediaHTTPConnection_native_init(JNIEnv *env) {
+    ScopedLocalRef<jclass> clazz(
+            env, env->FindClass("android/media/MediaHTTPConnection"));
+    CHECK(clazz.get() != NULL);
+
+    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "I");
+    CHECK(gFields.context != NULL);
+
+    gFields.readAtMethodID = env->GetMethodID(clazz.get(), "readAt", "(J[BI)I");
+}
+
+static void android_media_MediaHTTPConnection_native_setup(
+        JNIEnv *env, jobject thiz) {
+    sp<JMediaHTTPConnection> conn = new JMediaHTTPConnection(env, thiz);
+
+    setObject(env, thiz, conn);
+}
+
+static void android_media_MediaHTTPConnection_native_finalize(
+        JNIEnv *env, jobject thiz) {
+    setObject(env, thiz, NULL);
+}
+
+static jobject android_media_MediaHTTPConnection_native_getIMemory(
+        JNIEnv *env, jobject thiz) {
+    sp<JMediaHTTPConnection> conn = getObject(env, thiz);
+
+    return javaObjectForIBinder(env, conn->getIMemory()->asBinder());
+}
+
+static jint android_media_MediaHTTPConnection_native_readAt(
+        JNIEnv *env, jobject thiz, jlong offset, jint size) {
+    sp<JMediaHTTPConnection> conn = getObject(env, thiz);
+
+    if (size > JMediaHTTPConnection::kBufferSize) {
+        size = JMediaHTTPConnection::kBufferSize;
+    }
+
+    jbyteArray byteArrayObj = conn->getByteArrayObj();
+
+    jint n = env->CallIntMethod(
+            thiz, gFields.readAtMethodID, offset, byteArrayObj, size);
+
+    if (n > 0) {
+        env->GetByteArrayRegion(
+                byteArrayObj,
+                0,
+                n,
+                (jbyte *)conn->getIMemory()->pointer());
+    }
+
+    return n;
+}
+
+static JNINativeMethod gMethods[] = {
+    { "native_getIMemory", "()Landroid/os/IBinder;",
+      (void *)android_media_MediaHTTPConnection_native_getIMemory },
+
+    { "native_readAt", "(JI)I",
+      (void *)android_media_MediaHTTPConnection_native_readAt },
+
+    { "native_init", "()V",
+      (void *)android_media_MediaHTTPConnection_native_init },
+
+    { "native_setup", "()V",
+      (void *)android_media_MediaHTTPConnection_native_setup },
+
+    { "native_finalize", "()V",
+      (void *)android_media_MediaHTTPConnection_native_finalize },
+};
+
+int register_android_media_MediaHTTPConnection(JNIEnv *env) {
+    return AndroidRuntime::registerNativeMethods(env,
+                "android/media/MediaHTTPConnection", gMethods, NELEM(gMethods));
+}
+
diff --git a/media/jni/android_media_MediaHTTPConnection.h b/media/jni/android_media_MediaHTTPConnection.h
new file mode 100644
index 0000000..62ff678
--- /dev/null
+++ b/media/jni/android_media_MediaHTTPConnection.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ * 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIAHTTPCONNECTION_H_
+#define _ANDROID_MEDIA_MEDIAHTTPCONNECTION_H_
+
+#include "jni.h"
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct IMemory;
+struct MemoryDealer;
+
+struct JMediaHTTPConnection : public RefBase {
+    enum {
+        kBufferSize = 32768,
+    };
+
+    JMediaHTTPConnection(JNIEnv *env, jobject thiz);
+
+    sp<IMemory> getIMemory();
+
+    jbyteArray getByteArrayObj();
+
+protected:
+    virtual ~JMediaHTTPConnection();
+
+private:
+    jclass mClass;
+    jweak mObject;
+    jbyteArray mByteArrayObj;
+
+    sp<MemoryDealer> mDealer;
+    sp<IMemory> mMemory;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMediaHTTPConnection);
+};
+
+}  // namespace android
+
+#endif  // _ANDROID_MEDIA_MEDIAHTTPCONNECTION_H_
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index a52b24d..f17209f 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -22,6 +22,7 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 #include <core/SkBitmap.h>
+#include <media/IMediaHTTPService.h>
 #include <media/mediametadataretriever.h>
 #include <private/media/VideoFrame.h>
 
@@ -29,6 +30,7 @@
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_media_Utils.h"
+#include "android_util_Binder.h"
 
 
 using namespace android;
@@ -80,7 +82,7 @@
 
 static void
 android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
-        JNIEnv *env, jobject thiz, jstring path,
+        JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
         jobjectArray keys, jobjectArray values) {
 
     ALOGV("setDataSource");
@@ -122,10 +124,19 @@
             env, keys, values, &headersVector)) {
         return;
     }
+
+    sp<IMediaHTTPService> httpService;
+    if (httpServiceBinderObj != NULL) {
+        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
+        httpService = interface_cast<IMediaHTTPService>(binder);
+    }
+
     process_media_retriever_call(
             env,
             retriever->setDataSource(
-                pathStr.string(), headersVector.size() > 0 ? &headersVector : NULL),
+                httpService,
+                pathStr.string(),
+                headersVector.size() > 0 ? &headersVector : NULL),
 
             "java/lang/RuntimeException",
             "setDataSource failed");
@@ -442,7 +453,7 @@
 static JNINativeMethod nativeMethods[] = {
         {
             "_setDataSource",
-            "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
+            "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
             (void *)android_media_MediaMetadataRetriever_setDataSourceAndHeaders
         },
 
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 2c16a05..ea890c2 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -164,7 +164,7 @@
 }
 
 static void android_media_MediaMuxer_setLocation(
-        JNIEnv *env, jclass clazz, jint nativeObject, jint latitude, jint longitude) {
+        JNIEnv *env, jclass clazz, jlong nativeObject, jint latitude, jint longitude) {
     MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
 
     status_t res = muxer->setLocation(latitude, longitude);
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 9d0d5a6..2af1c12 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -20,6 +20,7 @@
 #include "utils/Log.h"
 
 #include <media/mediaplayer.h>
+#include <media/IMediaHTTPService.h>
 #include <media/MediaPlayerInterface.h>
 #include <stdio.h>
 #include <assert.h>
@@ -45,6 +46,7 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
+#include "android_util_Binder.h"
 // ----------------------------------------------------------------------------
 
 using namespace android;
@@ -183,7 +185,7 @@
 
 static void
 android_media_MediaPlayer_setDataSourceAndHeaders(
-        JNIEnv *env, jobject thiz, jstring path,
+        JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
         jobjectArray keys, jobjectArray values) {
 
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
@@ -214,8 +216,15 @@
         return;
     }
 
+    sp<IMediaHTTPService> httpService;
+    if (httpServiceBinderObj != NULL) {
+        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
+        httpService = interface_cast<IMediaHTTPService>(binder);
+    }
+
     status_t opStatus =
         mp->setDataSource(
+                httpService,
                 pathStr,
                 headersVector.size() > 0? &headersVector : NULL);
 
@@ -726,7 +735,8 @@
 }
 
 static jint
-android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
+android_media_MediaPlayer_pullBatteryData(
+        JNIEnv *env, jobject /* thiz */, jobject java_reply)
 {
     sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
     sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
@@ -856,8 +866,9 @@
 
 static JNINativeMethod gMethods[] = {
     {
-        "_setDataSource",
-        "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
+        "nativeSetDataSource",
+        "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
+        "[Ljava/lang/String;)V",
         (void *)android_media_MediaPlayer_setDataSourceAndHeaders
     },
 
@@ -911,6 +922,7 @@
 extern int register_android_media_MediaCodec(JNIEnv *env);
 extern int register_android_media_MediaExtractor(JNIEnv *env);
 extern int register_android_media_MediaCodecList(JNIEnv *env);
+extern int register_android_media_MediaHTTPConnection(JNIEnv *env);
 extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
 extern int register_android_media_MediaMuxer(JNIEnv *env);
 extern int register_android_media_MediaRecorder(JNIEnv *env);
@@ -922,7 +934,7 @@
 extern int register_android_mtp_MtpDevice(JNIEnv *env);
 extern int register_android_mtp_MtpServer(JNIEnv *env);
 
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
 {
     JNIEnv* env = NULL;
     jint result = -1;
@@ -1018,6 +1030,11 @@
         goto bail;
     }
 
+    if (register_android_media_MediaHTTPConnection(env) < 0) {
+        ALOGE("ERROR: MediaHTTPConnection native registration failed");
+        goto bail;
+    }
+
     /* success -- return valid version number */
     result = JNI_VERSION_1_4;
 
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index a94fedb..d1fed7bb 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -27,6 +27,7 @@
 using android::INVALID_OPERATION;
 using android::Surface;
 using android::IGraphicBufferProducer;
+using android::IMediaHTTPService;
 using android::MediaPlayerBase;
 using android::OK;
 using android::Parcel;
@@ -57,6 +58,7 @@
     virtual bool        hardwareOutput() {return true;}
 
     virtual status_t    setDataSource(
+            const sp<IMediaHTTPService> &httpService,
             const char *url,
             const KeyedVector<String8, String8> *) {
         ALOGV("setDataSource %s", url);
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 70b30e6..d407a2c 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -192,7 +192,7 @@
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localisation désactivée"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Appareil multimédia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
-    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Appels d\'urgence uniquement"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Appels d\'urgence"</string>
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"Paramètres"</string>
     <string name="quick_settings_time_label" msgid="4635969182239736408">"Heure"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"Moi"</string>
@@ -200,7 +200,7 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Non connecté"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Aucun réseau"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi désactivé"</string>
-    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Écran sur lequel l\'affichage est diffusé"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Diffuser l\'écran"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 5579e19..eb2c44a 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -68,6 +68,7 @@
 
     private final Path mShapePath = new Path();
     private final Path mClipPath = new Path();
+    private final Path mTextPath = new Path();
 
     private class BatteryTracker extends BroadcastReceiver {
         public static final int UNKNOWN_LEVEL = -1;
@@ -190,9 +191,6 @@
         colors.recycle();
         mShowPercent = ENABLE_PERCENT && 0 != Settings.System.getInt(
                 context.getContentResolver(), "status_bar_show_battery_percent", 0);
-        if (mShowPercent) {
-            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-        }
         mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
 
         mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -353,6 +351,29 @@
             }
         }
 
+        // compute percentage text
+        boolean pctOpaque = false;
+        float pctX = 0, pctY = 0;
+        String pctText = null;
+        if (!tracker.plugged && level > EMPTY && mShowPercent
+                && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
+            mTextPaint.setColor(getColorForLevel(level));
+            mTextPaint.setTextSize(height *
+                    (SINGLE_DIGIT_PERCENT ? 0.75f
+                            : (tracker.level == 100 ? 0.38f : 0.5f)));
+            mTextHeight = -mTextPaint.getFontMetrics().ascent;
+            pctText = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
+            pctX = mWidth * 0.5f;
+            pctY = (mHeight + mTextHeight) * 0.47f;
+            pctOpaque = levelTop > pctY;
+            if (!pctOpaque) {
+                mTextPath.reset();
+                mTextPaint.getTextPath(pctText, 0, pctText.length(), pctX, pctY, mTextPath);
+                // cut the percentage text out of the overall shape
+                mShapePath.op(mTextPath, Path.Op.DIFFERENCE);
+            }
+        }
+
         // draw the battery shape background
         c.drawPath(mShapePath, mFramePaint);
 
@@ -369,29 +390,9 @@
                 final float x = mWidth * 0.5f;
                 final float y = (mHeight + mWarningTextHeight) * 0.48f;
                 c.drawText(mWarningString, x, y, mWarningTextPaint);
-            } else if (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
+            } else if (pctOpaque) {
                 // draw the percentage text
-                mTextPaint.setColor(getColorForLevel(level));
-                mTextPaint.setTextSize(height *
-                        (SINGLE_DIGIT_PERCENT ? 0.75f
-                                : (tracker.level == 100 ? 0.38f : 0.5f)));
-                mTextHeight = -mTextPaint.getFontMetrics().ascent;
-
-                final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
-                final float x = mWidth * 0.5f;
-                final float y = (mHeight + mTextHeight) * 0.47f;
-
-                boolean opaque = levelTop > y;
-                if (opaque) {
-                    mTextPaint.setXfermode(null);
-                } else {
-                    mTextPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
-                }
-
-                c.drawText(str,
-                        x,
-                        y,
-                        mTextPaint);
+                c.drawText(pctText, pctX, pctY, mTextPaint);
             }
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 7c0735b..f82ca22 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -591,7 +591,7 @@
                 icon.setImageDrawable(mIcon);
                 icon.setScaleType(ScaleType.CENTER_CROP);
             } else if (mIconResId != 0) {
-                icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
+                icon.setImageDrawable(context.getDrawable(mIconResId));
             }
             if (mMessage != null) {
                 messageView.setText(mMessage);
@@ -681,7 +681,7 @@
 
             boolean on = ((mState == State.On) || (mState == State.TurningOn));
             if (icon != null) {
-                icon.setImageDrawable(context.getResources().getDrawable(
+                icon.setImageDrawable(context.getDrawable(
                         (on ? mEnabledIconResId : mDisabledIconResid)));
                 icon.setEnabled(enabled);
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index d0abe9c..c73d90a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,8 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.*;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
 import android.app.ActivityOptions;
 import android.transition.Scene;
 import android.transition.Transition;
@@ -88,6 +90,7 @@
 import android.view.ViewParent;
 import android.view.ViewRootImpl;
 import android.view.ViewStub;
+import android.view.ViewTreeObserver;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
@@ -114,6 +117,8 @@
     private final static String TAG = "PhoneWindow";
 
     private final static boolean SWEEP_OPEN_MENU = false;
+    private static final long MAX_TRANSITION_START_WAIT = 500;
+    private static final long MAX_TRANSITION_FINISH_WAIT = 1000;
 
     /**
      * Simple callback used by the context menu and its submenus. The options
@@ -136,22 +141,21 @@
     private ViewGroup mContentParent;
 
     SurfaceHolder.Callback2 mTakeSurfaceCallback;
-    
+
     InputQueue.Callback mTakeInputQueueCallback;
-    
+
     private boolean mIsFloating;
 
     private LayoutInflater mLayoutInflater;
 
     private TextView mTitleView;
-    
+
     private ActionBarView mActionBar;
     private ActionMenuPresenterCallback mActionMenuPresenterCallback;
     private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
 
     private TransitionManager mTransitionManager;
     private Scene mContentScene;
-    private Bundle mTransitionOptions;
 
     // The icon resource has been explicitly set elsewhere
     // and should not be overwritten with a default.
@@ -233,6 +237,10 @@
         }
     };
 
+    private ActivityOptions mActivityOptions;
+    private SceneTransitionListener mSceneTransitionListener;
+    private boolean mFadeEarly = true;
+
     static class WindowManagerHolder {
         static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService("window"));
@@ -303,11 +311,6 @@
     }
 
     @Override
-    public void setTransitionOptions(Bundle options) {
-        mTransitionOptions = options;
-    }
-
-    @Override
     public void setContentView(int layoutResID) {
         // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
         // decor, when theme attributes and the like are crystalized. Do not check the feature
@@ -378,26 +381,11 @@
     }
 
     private void transitionTo(Scene scene) {
-        Transition selected = null;
-        if (mTransitionOptions != null) {
-            final ActivityOptions opts = new ActivityOptions(mTransitionOptions);
-            mTransitionOptions = null;
-
-            String selectedName = null;
-            for (String sceneName : opts.getDestSceneNames()) {
-                final Transition t = mTransitionManager.getNamedTransition(sceneName, scene);
-                if (t != null) {
-                    // TODO handle args/state; inject into t/clone with params
-                    selected = t;
-                    selectedName = sceneName;
-                    break;
-                }
+        if (mContentScene == null) {
+            scene.enter();
+            if (mActivityOptions != null) {
+                new EnterScene().start();
             }
-            opts.dispatchSceneTransitionStarted(selectedName);
-        }
-
-        if (selected != null) {
-            TransitionManager.go(scene, selected);
         } else {
             mTransitionManager.transitionTo(scene);
         }
@@ -413,11 +401,11 @@
     public void takeSurface(SurfaceHolder.Callback2 callback) {
         mTakeSurfaceCallback = callback;
     }
-    
+
     public void takeInputQueue(InputQueue.Callback callback) {
         mTakeInputQueueCallback = callback;
     }
-    
+
     @Override
     public boolean isFloating() {
         return mIsFloating;
@@ -704,7 +692,7 @@
                 // Otherwise, set the normal panel background
                 backgroundResId = st.background;
             }
-            st.decorView.setWindowBackground(getContext().getResources().getDrawable(
+            st.decorView.setWindowBackground(getContext().getDrawable(
                     backgroundResId));
 
             ViewParent shownPanelParent = st.shownPanelView.getParent();
@@ -1289,7 +1277,7 @@
             if (st.resid != resId) {
                 st.resid = resId;
                 st.uri = null;
-                st.local = getContext().getResources().getDrawable(resId);
+                st.local = getContext().getDrawable(resId);
                 updateDrawable(featureId, st, false);
             }
         } else {
@@ -2305,7 +2293,7 @@
                     if (mMenuBackground == null && mFeatureId < 0
                             && getAttributes().height
                             == WindowManager.LayoutParams.MATCH_PARENT) {
-                        mMenuBackground = getContext().getResources().getDrawable(
+                        mMenuBackground = getContext().getDrawable(
                                 com.android.internal.R.drawable.menu_background);
                     }
                     if (mMenuBackground != null) {
@@ -3122,12 +3110,12 @@
         if (getContainer() == null) {
             Drawable drawable = mBackgroundDrawable;
             if (mBackgroundResource != 0) {
-                drawable = getContext().getResources().getDrawable(mBackgroundResource);
+                drawable = getContext().getDrawable(mBackgroundResource);
             }
             mDecor.setWindowBackground(drawable);
             drawable = null;
             if (mFrameResource != 0) {
-                drawable = getContext().getResources().getDrawable(mFrameResource);
+                drawable = getContext().getDrawable(mFrameResource);
             }
             mDecor.setWindowFrame(drawable);
 
@@ -3553,6 +3541,12 @@
         return mVolumeControlStreamType;
     }
 
+    private boolean isTranslucent() {
+        TypedArray a = getWindowStyle();
+        return a.getBoolean(a.getResourceId(
+                com.android.internal.R.styleable.Window_windowIsTranslucent, 0), false);
+    }
+
     private static final class DrawableFeatureState {
         DrawableFeatureState(int _featureId) {
             featureId = _featureId;
@@ -3986,4 +3980,218 @@
     void sendCloseSystemWindows(String reason) {
         PhoneWindowManager.sendCloseSystemWindows(getContext(), reason);
     }
+
+    @Override
+    public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
+        mSceneTransitionListener = listener;
+        mActivityOptions = options;
+    }
+
+    @Override
+    public void setEarlyBackgroundTransition(boolean fadeEarly) {
+        mFadeEarly = fadeEarly;
+    }
+
+    @Override
+    public void startExitTransition(ActivityOptions activityOptions) {
+        Transition transition = mTransitionManager.getNamedTransition(getContentScene(), "null");
+        if (transition == null) {
+            transition = TransitionManager.getDefaultTransition().clone();
+        }
+        activityOptions.setExitTransition(transition, new ActivityOptions.SharedElementSource() {
+            @Override
+            public int getTextureId() {
+                // TODO: move shared elements to a layer and return the texture id
+                recurseHideExitingSharedElements(mContentParent);
+                return 0;
+            }
+        });
+        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);
+            } else {
+                child.setVisibility(View.INVISIBLE);
+            }
+        }
+    }
+
+    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);
+            }
+        }
+    }
+
+    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);
+            }
+        }
+    }
+
+    /**
+     * Provides code for handling the Activity transition entering scene.
+     * When the first scene is laid out (onPreDraw), it makes views invisible.
+     * It then starts the entering transition by making non-shared elements visible. When
+     * the entering transition is started, the calling Activity is notified that
+     * this Activity is ready to receive the shared element. When the calling Activity notifies
+     * that the shared element is ready, this Activity is notified through the
+     * SceneTransitionListener.
+     *
+     * This class also takes into account fading the background -- either waiting until the
+     * shared element is ready or the calling Activity's exit transition is complete.
+     */
+    private class EnterScene implements ViewTreeObserver.OnPreDrawListener, Runnable,
+            ActivityOptions.ActivityTransitionTarget, Animator.AnimatorListener {
+        private boolean mSharedElementReadyReceived;
+        private boolean mAllDone;
+        private Handler mHandler = new Handler();
+        private boolean mEnterTransitionStarted;
+        private ArrayList<View> mSharedElements = new ArrayList<View>();
+
+        public EnterScene() {
+            mSceneTransitionListener.nullPendingTransition();
+            Drawable background = getDecorView().getBackground();
+            if (background != null) {
+                setBackgroundDrawable(null);
+                background.setAlpha(0);
+                setBackgroundDrawable(background);
+            }
+            mSceneTransitionListener.convertToTranslucent();
+        }
+
+        @Override
+        public boolean onPreDraw() {
+            ViewTreeObserver observer = mContentParent.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();
+                }
+                TransitionManager.beginDelayedTransition(mContentParent, transition);
+                for (View hidden : enteringViews) {
+                    hidden.setVisibility(View.VISIBLE);
+                }
+                observer.addOnPreDrawListener(this);
+            } else {
+                mHandler.postDelayed(this, MAX_TRANSITION_START_WAIT);
+                mActivityOptions.dispatchSceneTransitionStarted(this);
+            }
+            return true;
+        }
+
+        public void start() {
+            ViewTreeObserver observer = mContentParent.getViewTreeObserver();
+            observer.addOnPreDrawListener(this);
+        }
+
+        @Override
+        public void run() {
+            exitTransitionComplete();
+        }
+
+        @Override
+        public void sharedElementTransitionComplete() {
+            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 (mFadeEarly) {
+                    fadeInBackground();
+                }
+            }
+        }
+
+        private void fadeInBackground() {
+            Drawable background = getDecorView().getBackground();
+            if (background == null) {
+                mSceneTransitionListener.convertFromTranslucent();
+            } else {
+                ObjectAnimator animator = ObjectAnimator.ofInt(background, "alpha", 255);
+                animator.addListener(this);
+                animator.start();
+            }
+        }
+
+        @Override
+        public void exitTransitionComplete() {
+            if (mAllDone) {
+                return;
+            }
+            mAllDone = true;
+            sharedElementTransitionComplete();
+            mHandler.removeCallbacks(this);
+            if (!mFadeEarly) {
+                fadeInBackground();
+            }
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mSceneTransitionListener.convertFromTranslucent();
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 015185f..9349730 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -169,9 +169,9 @@
     private static final String TAG = "ConnectivityService";
 
     private static final boolean DBG = true;
-    private static final boolean VDBG = false;
+    private static final boolean VDBG = true;
 
-    private static final boolean LOGD_RULES = false;
+    private static final boolean LOGD_RULES = true;
 
     // TODO: create better separation between radio types and network types
 
@@ -4495,11 +4495,16 @@
          * @param seconds
          */
         private static void sleep(int seconds) {
-            try {
-                Thread.sleep(seconds * 1000);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
+            log("XXXXX sleeping for " + seconds + " sec");
+            long stopTime = System.nanoTime() + (seconds * 1000000000);
+            long sleepTime;
+            while ((sleepTime = stopTime - System.nanoTime()) > 0) {
+                try {
+                    Thread.sleep(sleepTime / 1000000);
+                } catch (InterruptedException ignored) {
+                }
             }
+            log("XXXXX returning from sleep");
         }
 
         private static void log(String s) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a21157f..8693c31 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3125,7 +3125,7 @@
             }
         }
         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
-                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
+                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
         return ret;
     }
 
@@ -3237,7 +3237,8 @@
 
     final int startActivityInPackage(int uid, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
-            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
+            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
+                    IActivityContainer container) {
 
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
@@ -3245,7 +3246,7 @@
         // TODO: Switch to user app stacks here.
         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
-                null, null, null, null, options, userId, null);
+                null, null, null, null, options, userId, container);
         return ret;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 70d85fc..4a07256 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -738,6 +738,12 @@
             mStackSupervisor.resumeTopActivitiesLocked();
             return;
         }
+
+        if (mActivityContainer.mParentActivity == null) {
+            // Top level stack, not a child. Look for child stacks.
+            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping);
+        }
+
         if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
         else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
         mResumedActivity = null;
@@ -1282,6 +1288,13 @@
     final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
         if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
 
+        ActivityRecord parent = mActivityContainer.mParentActivity;
+        if (parent != null && parent.state != ActivityState.RESUMED) {
+            // Do not resume this stack if its parent is not resumed.
+            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
+            return false;
+        }
+
         cancelInitializingActivities();
 
         // Find the first activity that is not finishing.
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6115f06..a33b0e5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -277,6 +277,10 @@
     // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the
     // top of all visible stacks.
     boolean isFrontStack(ActivityStack stack) {
+        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
+        if (parent != null) {
+            stack = parent.task.stack;
+        }
         ArrayList<ActivityStack> stacks = stack.mStacks;
         if (stacks != null && !stacks.isEmpty()) {
             return stack == stacks.get(stacks.size() - 1);
@@ -510,6 +514,20 @@
         return pausing;
     }
 
+    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
+		// 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) {
+                final ActivityStack stack = stacks.get(stackNdx);
+                if (stack.mResumedActivity != null &&
+                        stack.mActivityContainer.mParentActivity == parent) {
+                    stack.startPausingLocked(userLeaving, uiSleeping);
+                }
+            }
+        }
+    }
+
     void reportActivityVisibleLocked(ActivityRecord r) {
         for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
             WaitResult w = mWaitingActivityVisible.get(i);
@@ -2915,7 +2933,7 @@
             mStack.mStacks = activityDisplay.mStacks;
 
             activityDisplay.attachActivities(mStack);
-            mWindowManager.createStack(mStackId, activityDisplay.mDisplayId);
+            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
         }
 
         @Override
@@ -2945,6 +2963,7 @@
                 mActivityDisplay = null;
                 mStack.mDisplayId = -1;
                 mStack.mStacks = null;
+                mWindowManager.detachStack(mStackId);
             }
         }
 
@@ -2957,7 +2976,7 @@
 
         @Override
         public final int startActivity(Intent intent) {
-            mService.enforceNotIsolatedCaller("ActivityContainer");
+            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
             int userId = mService.handleIncomingUser(Binder.getCallingPid(),
                     Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
             // TODO: Switch to user app stacks here.
@@ -2971,20 +2990,40 @@
         }
 
         @Override
+        public final int startActivityIntentSender(IIntentSender intentSender) {
+            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
+
+            if (!(intentSender instanceof PendingIntentRecord)) {
+                throw new IllegalArgumentException("Bad PendingIntent object");
+            }
+
+            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
+                    null, 0, 0, 0, null, this);
+        }
+
+        @Override
         public IBinder asBinder() {
             return this;
         }
 
         @Override
         public void attachToSurface(Surface surface, int width, int height, int density) {
-            synchronized (mService) {
-                ActivityDisplay activityDisplay =
-                        new ActivityDisplay(surface, width, height, density);
-                mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
-                attachToDisplayLocked(activityDisplay);
+            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
+
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                synchronized (mService) {
+                    ActivityDisplay activityDisplay =
+                            new ActivityDisplay(surface, width, height, density);
+                    mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
+                    attachToDisplayLocked(activityDisplay);
+                    mStack.resumeTopActivityLocked(null);
+                }
+                if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
+                        + mActivityDisplay);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
             }
-            if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
-                    + mActivityDisplay);
         }
 
         ActivityStackSupervisor getOuter() {
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 17f24a9..00fa216 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import android.app.ActivityManager;
+import android.app.IActivityContainer;
 import android.content.IIntentSender;
 import android.content.IIntentReceiver;
 import android.app.PendingIntent;
@@ -190,13 +191,13 @@
     public int send(int code, Intent intent, String resolvedType,
             IIntentReceiver finishedReceiver, String requiredPermission) {
         return sendInner(code, intent, resolvedType, finishedReceiver,
-                requiredPermission, null, null, 0, 0, 0, null);
+                requiredPermission, null, null, 0, 0, 0, null, null);
     }
     
     int sendInner(int code, Intent intent, String resolvedType,
             IIntentReceiver finishedReceiver, String requiredPermission,
             IBinder resultTo, String resultWho, int requestCode,
-            int flagsMask, int flagsValues, Bundle options) {
+            int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {
         synchronized(owner) {
             if (!canceled) {
                 sent = true;
@@ -251,7 +252,7 @@
                             } else {
                                 owner.startActivityInPackage(uid, key.packageName, finalIntent,
                                         resolvedType, resultTo, resultWho, requestCode, 0,
-                                        options, userId);
+                                        options, userId, container);
                             }
                         } catch (RuntimeException e) {
                             Slog.w(ActivityManagerService.TAG,
@@ -302,7 +303,8 @@
         }
         return ActivityManager.START_CANCELED;
     }
-    
+
+    @Override
     protected void finalize() throws Throwable {
         try {
             if (!canceled) {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 978d5b7..30eaf45 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -51,9 +51,9 @@
     /** Owning stack */
     final TaskStack mStack;
 
-    DimLayer(WindowManagerService service, TaskStack stack) {
+    DimLayer(WindowManagerService service, TaskStack stack, DisplayContent displayContent) {
         mStack = stack;
-        mDisplayContent = stack.getDisplayContent();
+        mDisplayContent = displayContent;
         final int displayId = mDisplayContent.getDisplayId();
         if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
         SurfaceControl.openTransaction();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0a070c1..9f45e88 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
-import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerService.TAG;
 
@@ -116,7 +115,7 @@
 
     /**
      * @param display May not be null.
-     * @param service TODO(cmautner):
+     * @param service You know.
      */
     DisplayContent(Display display, WindowManagerService service) {
         mDisplay = display;
@@ -236,19 +235,16 @@
         return count;
     }
 
-    /** Refer to {@link WindowManagerService#createStack(int, int)} */
-    TaskStack createStack(int stackId) {
-        if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId);
-        TaskStack newStack = new TaskStack(mService, stackId, this);
-        if (stackId == HOME_STACK_ID) {
+    /** Refer to {@link WindowManagerService#attachStack(int, int)} */
+    void attachStack(TaskStack stack) {
+        if (stack.mStackId == HOME_STACK_ID) {
             if (mHomeStack != null) {
-                throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first.");
+                throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
             }
-            mHomeStack = newStack;
+            mHomeStack = stack;
         }
-        mStacks.add(newStack);
+        mStacks.add(stack);
         layoutNeeded = true;
-        return newStack;
     }
 
     void moveStack(TaskStack stack, boolean toTop) {
@@ -256,12 +252,15 @@
         mStacks.add(toTop ? mStacks.size() : 0, stack);
     }
 
-    TaskStack removeStack(TaskStack stack) {
-        mStacks.remove(stack);
-        if (!mStacks.isEmpty()) {
-            return mStacks.get(mStacks.size() - 1);
+    void detachStack(TaskStack stack) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final Task task = mTaskHistory.get(taskNdx);
+            if (task.mStack == stack) {
+                mService.tmpRemoveTaskWindowsLocked(task);
+                mTaskHistory.remove(taskNdx);
+            }
         }
-        return null;
+        mStacks.remove(stack);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 87cabc9..ca9076f 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -293,7 +293,11 @@
             // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
             // the actual drag event dispatch stuff in the dragstate
 
-            Display display = callingWin.mDisplayContent.getDisplay();
+            final DisplayContent displayContent = callingWin.getDisplayContent();
+            if (displayContent == null) {
+               return false;
+            }
+            Display display = displayContent.getDisplay();
             mService.mDragState.register(display);
             mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
             if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index a1704a6..44f2596 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -45,7 +45,6 @@
         if (mAppTokens.size() == 0) {
             EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_REMOVED, taskId,
                     "removeAppToken: last token");
-            mStack.removeTask(this);
             return true;
         }
         return false;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index aa6b0c9..1ada6c2 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -41,7 +41,7 @@
     private final WindowManagerService mService;
 
     /** The display this stack sits under. */
-    private final DisplayContent mDisplayContent;
+    private DisplayContent mDisplayContent;
 
     /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
      * mTaskHistory in the ActivityStack with the same mStackId */
@@ -52,13 +52,13 @@
     Rect mBounds = new Rect();
 
     /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
-    final DimLayer mDimLayer;
+    DimLayer mDimLayer;
 
     /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
     WindowStateAnimator mDimWinAnimator;
 
     /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
-    final DimLayer mAnimationBackgroundSurface;
+    DimLayer mAnimationBackgroundSurface;
 
     /** The particular window with an Animation with non-zero background color. */
     WindowStateAnimator mAnimationBackgroundAnimator;
@@ -67,12 +67,9 @@
      * then stop any dimming. */
     boolean mDimmingTag;
 
-    TaskStack(WindowManagerService service, int stackId, DisplayContent displayContent) {
+    TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
-        mDisplayContent = displayContent;
-        mDimLayer = new DimLayer(service, this);
-        mAnimationBackgroundSurface = new DimLayer(service, this);
         // TODO: remove bounds from log, they are always 0.
         EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
                 mBounds.right, mBounds.bottom);
@@ -121,12 +118,16 @@
     }
 
     void getBounds(Rect out) {
-        if (mBounds.isEmpty()) {
-            mDisplayContent.getLogicalDisplayRect(out);
+        if (mDisplayContent != null) {
+            if (mBounds.isEmpty()) {
+                mDisplayContent.getLogicalDisplayRect(out);
+            } else {
+                out.set(mBounds);
+            }
+            out.intersect(mDisplayContent.mContentRect);
         } else {
             out.set(mBounds);
         }
-        out.intersect(mDisplayContent.mContentRect);
     }
 
     boolean isFullscreen() {
@@ -198,22 +199,37 @@
     void removeTask(Task task) {
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
         mTasks.remove(task);
-        mDisplayContent.removeTask(task);
-        if (mTasks.isEmpty()) {
-            mDisplayContent.moveStack(this, false);
+        if (mDisplayContent != null) {
+            mDisplayContent.removeTask(task);
+            if (mTasks.isEmpty()) {
+                mDisplayContent.moveStack(this, false);
+            }
+            mDisplayContent.layoutNeeded = true;
         }
-        mDisplayContent.layoutNeeded = true;
     }
 
-    int remove() {
-        mAnimationBackgroundSurface.destroySurface();
-        mDimLayer.destroySurface();
-        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
-        TaskStack next = mDisplayContent.removeStack(this);
-        if (next != null) {
-            return next.mStackId;
+    void attachDisplayContent(DisplayContent displayContent) {
+        if (mDisplayContent != null) {
+            throw new IllegalStateException("attachDisplayContent: Already attached");
         }
-        return -1;
+
+        mDisplayContent = displayContent;
+        mDimLayer = new DimLayer(mService, this, displayContent);
+        mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
+
+        for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
+            Task task = mTasks.get(taskNdx);
+            displayContent.addTask(task, true);
+        }
+    }
+
+    void detach() {
+        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
+        mAnimationBackgroundSurface.destroySurface();
+        mAnimationBackgroundSurface = null;
+        mDimLayer.destroySurface();
+        mDimLayer = null;
+        mDisplayContent = null;
     }
 
     void resetAnimationBackgroundAnimator() {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 91f15f3..b4285c6 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -642,11 +642,16 @@
     }
 
     int getPendingLayoutChanges(final int displayId) {
+        if (displayId < 0) {
+            return 0;
+        }
         return mService.getDisplayContentLocked(displayId).pendingLayoutChanges;
     }
 
     void setPendingLayoutChanges(final int displayId, final int changes) {
-        mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes;
+        if (displayId >= 0) {
+            mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes;
+        }
     }
 
     void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) {
@@ -655,7 +660,7 @@
         WindowList windows = appAnimator.mAppToken.allAppWindows;
         for (int i = windows.size() - 1; i >= 0; i--) {
             final int displayId = windows.get(i).getDisplayId();
-            if (displays.indexOfKey(displayId) < 0) {
+            if (displayId >= 0 && displays.indexOfKey(displayId) < 0) {
                 setPendingLayoutChanges(displayId, changes);
                 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
                     mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId));
@@ -676,10 +681,15 @@
     }
 
     void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) {
-        getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation;
+        if (displayId >= 0) {
+            getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation;
+        }
     }
 
     ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) {
+        if (displayId < 0) {
+            return null;
+        }
         return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6c7fb26..5387436 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -155,8 +155,7 @@
 
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
-        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
-        DisplayManager.DisplayListener {
+        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
     static final String TAG = "WindowManager";
     static final boolean DEBUG = false;
     static final boolean DEBUG_ADD_REMOVE = false;
@@ -269,10 +268,10 @@
     // Default input dispatching timeout in nanoseconds.
     static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
 
-    /** Minimum value for createStack and resizeStack weight value */
+    /** Minimum value for attachStack and resizeStack weight value */
     public static final float STACK_WEIGHT_MIN = 0.2f;
 
-    /** Maximum value for createStack and resizeStack weight value */
+    /** Maximum value for attachStack and resizeStack weight value */
     public static final float STACK_WEIGHT_MAX = 0.8f;
 
     static final int UPDATE_FOCUS_NORMAL = 0;
@@ -742,7 +741,6 @@
 
         mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
-        mDisplayManager.registerDisplayListener(this, null);
         Display[] displays = mDisplayManager.getDisplays();
         for (Display display : displays) {
             createDisplayContentLocked(display);
@@ -874,7 +872,7 @@
         final int count = token.windows.size();
         for (int i = 0; i < count; i++) {
             final WindowState win = token.windows.get(i);
-            if (win.mDisplayContent == displayContent) {
+            if (win.getDisplayContent() == displayContent) {
                 windowList.add(win);
             }
         }
@@ -905,7 +903,7 @@
     private int addAppWindowToListLocked(final WindowState win) {
         final IWindow client = win.mClient;
         final WindowToken token = win.mToken;
-        final DisplayContent displayContent = win.mDisplayContent;
+        final DisplayContent displayContent = win.getDisplayContent();
 
         final WindowList windows = win.getWindowList();
         final int N = windows.size();
@@ -1082,7 +1080,7 @@
 
     private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
         final WindowToken token = win.mToken;
-        final DisplayContent displayContent = win.mDisplayContent;
+        final DisplayContent displayContent = win.getDisplayContent();
         final WindowState attached = win.mAttachedWindow;
 
         WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
@@ -2016,7 +2014,10 @@
     }
 
     void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
-        final DisplayContent displayContent = changingTarget.mDisplayContent;
+        final DisplayContent displayContent = changingTarget.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final int dw = displayInfo.logicalWidth;
         final int dh = displayInfo.logicalHeight;
@@ -2076,7 +2077,10 @@
 
     void updateWallpaperVisibilityLocked() {
         final boolean visible = isWallpaperVisible(mWallpaperTarget);
-        final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
+        final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final int dw = displayInfo.logicalWidth;
         final int dh = displayInfo.logicalHeight;
@@ -2428,7 +2432,10 @@
                 //Slog.i(TAG, "*** Running exit animation...");
                 win.mExiting = true;
                 win.mRemoveOnExit = true;
-                win.mDisplayContent.layoutNeeded = true;
+                final DisplayContent displayContent = win.getDisplayContent();
+                if (displayContent != null) {
+                    displayContent.layoutNeeded = true;
+                }
                 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
                         false /*updateInputWindows*/);
                 performLayoutAndPlaceSurfacesLocked();
@@ -2485,8 +2492,6 @@
             mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
         }
 
-        final WindowList windows = win.getWindowList();
-        windows.remove(win);
         mPendingRemove.remove(win);
         mResizingWindows.remove(win);
         mWindowsChanged = true;
@@ -2541,12 +2546,19 @@
                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
         }
 
-        if (!mInLayout) {
-            assignLayersLocked(windows);
-            win.mDisplayContent.layoutNeeded = true;
-            performLayoutAndPlaceSurfacesLocked();
-            if (win.mAppToken != null) {
-                win.mAppToken.updateReportedVisibilityLocked();
+        final WindowList windows = win.getWindowList();
+        if (windows != null) {
+            windows.remove(win);
+            if (!mInLayout) {
+                assignLayersLocked(windows);
+                final DisplayContent displayContent = win.getDisplayContent();
+                if (displayContent != null) {
+                    displayContent.layoutNeeded = true;
+                }
+                performLayoutAndPlaceSurfacesLocked();
+                if (win.mAppToken != null) {
+                    win.mAppToken.updateReportedVisibilityLocked();
+                }
             }
         }
 
@@ -2621,7 +2633,10 @@
                         w.mGivenVisibleInsets.scale(w.mGlobalScale);
                         w.mGivenTouchableRegion.scale(w.mGlobalScale);
                     }
-                    w.mDisplayContent.layoutNeeded = true;
+                    final DisplayContent displayContent = w.getDisplayContent();
+                    if (displayContent != null) {
+                        displayContent.layoutNeeded = true;
+                    }
                     performLayoutAndPlaceSurfacesLocked();
                 }
             }
@@ -2707,7 +2722,12 @@
         mTmpFloats[Matrix.MSKEW_X] = dsdy;
         mTmpFloats[Matrix.MSCALE_Y] = dtdy;
         matrix.setValues(mTmpFloats);
-        final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
+        final DisplayContent displayContent = window.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
+
+        final DisplayInfo displayInfo = window.getDisplayContent().getDisplayInfo();
         final RectF dispRect = new RectF(0, 0,
                 displayInfo.logicalWidth, displayInfo.logicalHeight);
         matrix.mapRect(dispRect);
@@ -2716,7 +2736,7 @@
         window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
                 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
         window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
-        window.mDisplayContent.layoutNeeded = true;
+        displayContent.layoutNeeded = true;
         performLayoutAndPlaceSurfacesLocked();
     }
 
@@ -2997,7 +3017,10 @@
                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
             }
 
-            win.mDisplayContent.layoutNeeded = true;
+            final DisplayContent displayContent = win.getDisplayContent();
+            if (displayContent != null) {
+                displayContent.layoutNeeded = true;
+            }
             win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
             configChanged = updateOrientationFromAppTokensLocked(false);
             performLayoutAndPlaceSurfacesLocked();
@@ -3091,7 +3114,10 @@
                         getDefaultDisplayContentLocked().pendingLayoutChanges |=
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                     }
-                    win.mDisplayContent.layoutNeeded = true;
+                    final DisplayContent displayContent = win.getDisplayContent();
+                    if (displayContent != null) {
+                        displayContent.layoutNeeded = true;
+                    }
                     requestTraversalLocked();
                 }
             }
@@ -3349,7 +3375,7 @@
 
                     for (int i=0; i<N; i++) {
                         WindowState win = wtoken.windows.get(i);
-                        displayContent = win.mDisplayContent;
+                        displayContent = win.getDisplayContent();
 
                         if (win.mWinAnimator.isAnimating()) {
                             delayed = true;
@@ -3364,7 +3390,9 @@
                                         WindowManagerPolicy.TRANSIT_EXIT);
                             }
                             changed = true;
-                            displayContent.layoutNeeded = true;
+                            if (displayContent != null) {
+                                displayContent.layoutNeeded = true;
+                            }
                         }
                     }
 
@@ -3377,7 +3405,9 @@
                     }
 
                     if (delayed) {
-                        displayContent.mExitingTokens.add(wtoken);
+                        if (displayContent != null) {
+                            displayContent.mExitingTokens.add(wtoken);
+                        }
                     } else if (wtoken.windowType == TYPE_WALLPAPER) {
                         mWallpaperTokens.remove(wtoken);
                     }
@@ -3473,8 +3503,8 @@
                 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
                 return;
             }
-            Task oldTask = mTaskIdToTask.get(atoken.groupId);
-            oldTask.removeAppToken(atoken);
+            final Task oldTask = mTaskIdToTask.get(atoken.groupId);
+            removeAppFromTask(atoken);
 
             atoken.groupId = groupId;
             Task newTask = mTaskIdToTask.get(groupId);
@@ -3767,7 +3797,10 @@
         if (mFocusedApp != null) {
             Task task = mTaskIdToTask.get(mFocusedApp.groupId);
             stack = task.mStack;
-            task.getDisplayContent().setTouchExcludeRegion(stack);
+            final DisplayContent displayContent = task.getDisplayContent();
+            if (displayContent != null) {
+                displayContent.setTouchExcludeRegion(stack);
+            }
         } else {
             stack = null;
         }
@@ -4224,7 +4257,10 @@
                             }
                         }
                         changed = true;
-                        win.mDisplayContent.layoutNeeded = true;
+                        final DisplayContent displayContent = win.getDisplayContent();
+                        if (displayContent != null) {
+                            displayContent.layoutNeeded = true;
+                        }
                     }
                 } else if (win.isVisibleNow()) {
                     if (!runningAppAnimation) {
@@ -4238,7 +4274,10 @@
                         }
                     }
                     changed = true;
-                    win.mDisplayContent.layoutNeeded = true;
+                    final DisplayContent displayContent = win.getDisplayContent();
+                    if (displayContent != null) {
+                        displayContent.layoutNeeded = true;
+                    }
                 }
             }
 
@@ -4386,7 +4425,10 @@
                     }
                     w.mLastFreezeDuration = 0;
                     unfrozeWindows = true;
-                    w.mDisplayContent.layoutNeeded = true;
+                    final DisplayContent displayContent = w.getDisplayContent();
+                    if (displayContent != null) {
+                        displayContent.layoutNeeded = true;
+                    }
                 }
             }
             if (force || unfrozeWindows) {
@@ -4480,6 +4522,14 @@
         }
     }
 
+    void removeAppFromTask(AppWindowToken wtoken) {
+        final Task task = mTaskIdToTask.get(wtoken.groupId);
+        if (task != null && task.removeAppToken(wtoken)) {
+            task.mStack.removeTask(task);
+            mTaskIdToTask.delete(wtoken.groupId);
+        }
+    }
+
     @Override
     public void removeAppToken(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -4514,7 +4564,7 @@
                         + " animating=" + wtoken.mAppAnimator.animating);
                 final Task task = mTaskIdToTask.get(wtoken.groupId);
                 DisplayContent displayContent = task.getDisplayContent();
-                if (delayed) {
+                if (displayContent != null && delayed) {
                     // set the token aside because it has an active animation to be finished
                     if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                             "removeAppToken make exiting: " + wtoken);
@@ -4529,9 +4579,8 @@
                 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                         "removeAppToken: " + wtoken);
 
-                if (task.removeAppToken(wtoken)) {
-                    mTaskIdToTask.delete(wtoken.groupId);
-                }
+                removeAppFromTask(wtoken);
+
                 wtoken.removed = true;
                 if (wtoken.startingData != null) {
                     startingToken = wtoken;
@@ -4566,13 +4615,15 @@
             mH.sendMessage(m);
         }
     }
+
     private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
-        final int NW = token.windows.size();
+        WindowList windows = token.windows;
+        final int NW = windows.size();
         if (NW > 0) {
             mWindowsChanged = true;
         }
-        for (int i=0; i<NW; i++) {
-            WindowState win = token.windows.get(i);
+        for (int i = 0; i < NW; i++) {
+            WindowState win = windows.get(i);
             if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
             win.getWindowList().remove(win);
             int j = win.mChildWindows.size();
@@ -4605,12 +4656,13 @@
     }
 
     void dumpWindowsLocked() {
-        int i = 0;
         final int numDisplays = mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+            Slog.v(TAG, " Display #" + displayContent.getDisplayId());
+            final WindowList windows = displayContent.getWindowList();
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                Slog.v(TAG, "  #" + i++ + ": " + windows.get(winNdx));
+                Slog.v(TAG, "  #" + winNdx + ": " + windows.get(winNdx));
             }
         }
     }
@@ -4722,23 +4774,28 @@
         final int NW = token.windows.size();
         for (int i=0; i<NW; i++) {
             final WindowState win = token.windows.get(i);
-            if (win.mDisplayContent == displayContent) {
+            final DisplayContent winDisplayContent = win.getDisplayContent();
+            if (winDisplayContent == displayContent || winDisplayContent == null) {
+                win.mDisplayContent = displayContent;
                 index = reAddWindowLocked(index, win);
             }
         }
         return index;
     }
 
+    void tmpRemoveTaskWindowsLocked(Task task) {
+        AppTokenList tokens = task.mAppTokens;
+        for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+            tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
+        }
+    }
+
     void moveStackWindowsLocked(DisplayContent displayContent) {
         // First remove all of the windows from the list.
         final ArrayList<Task> tasks = displayContent.getTasks();
         final int numTasks = tasks.size();
         for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
-            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
-            final int numTokens = tokens.size();
-            for (int tokenNdx = numTokens - 1; tokenNdx >= 0; --tokenNdx) {
-                tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
-            }
+            tmpRemoveTaskWindowsLocked(tasks.get(taskNdx));
         }
 
         // And now add them back at the correct place.
@@ -4822,15 +4879,25 @@
      * @param stackId The unique identifier of the new stack.
      * @param displayId The unique identifier of the DisplayContent.
      */
-    public void createStack(int stackId, int displayId) {
+    public void attachStack(int stackId, int displayId) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mWindowMap) {
                 final DisplayContent displayContent = mDisplayContents.get(displayId);
                 if (displayContent != null) {
-                    TaskStack stack = displayContent.createStack(stackId);
-                    mStackIdToStack.put(stackId, stack);
-                    performLayoutAndPlaceSurfacesLocked();
+                    TaskStack stack = mStackIdToStack.get(stackId);
+                    if (stack == null) {
+                        if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId);
+                        stack = new TaskStack(this, stackId);
+                        mStackIdToStack.put(stackId, stack);
+                    }
+                    stack.attachDisplayContent(displayContent);
+                    displayContent.attachStack(stack);
+                    moveStackWindowsLocked(displayContent);
+                    final WindowList windows = displayContent.getWindowList();
+                    for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                        windows.get(winNdx).reportResized();
+                    }
                 }
             }
         } finally {
@@ -4838,6 +4905,19 @@
         }
     }
 
+    public void detachStack(int stackId) {
+        synchronized (mWindowMap) {
+            TaskStack stack = mStackIdToStack.get(stackId);
+            if (stack != null) {
+                final DisplayContent displayContent = stack.getDisplayContent();
+                if (displayContent != null) {
+                    displayContent.detachStack(stack);
+                    stack.detach();
+                }
+            }
+        }
+    }
+
     public void removeTask(int taskId) {
         synchronized (mWindowMap) {
             Task task = mTaskIdToTask.get(taskId);
@@ -7888,7 +7968,6 @@
     }
 
     final void rebuildAppWindowListLocked() {
-        // TODO: Multidisplay, when ActivityStacks and tasks exist on more than one display.
         rebuildAppWindowListLocked(getDefaultDisplayContentLocked());
     }
 
@@ -7953,7 +8032,8 @@
 
         i -= lastBelow;
         if (i != numRemoved) {
-            Slog.w(TAG, "Rebuild removed " + numRemoved + " windows but added " + i,
+            Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " +
+                    numRemoved + " windows but added " + i,
                     new RuntimeException("here").fillInStackTrace());
             for (i=0; i<numRemoved; i++) {
                 WindowState ws = mRebuildTmp[i];
@@ -8763,8 +8843,8 @@
             if (canBeSeen) {
                 // This function assumes that the contents of the default display are
                 // processed first before secondary displays.
-                final DisplayContent displayContent = w.mDisplayContent;
-                if (displayContent.isDefaultDisplay) {
+                final DisplayContent displayContent = w.getDisplayContent();
+                if (displayContent != null && displayContent.isDefaultDisplay) {
                     // While a dream or keyguard is showing, obscure ordinary application
                     // content on secondary displays (by forcibly enabling mirroring unless
                     // there is other content we want to show) but still allow opaque
@@ -8773,8 +8853,9 @@
                         mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
                     }
                     mInnerFields.mDisplayHasContent = true;
-                } else if (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
-                        || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG)) {
+                } else if (displayContent != null &&
+                        (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
+                        || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) {
                     // Allow full screen keyguard presentation dialogs to be seen.
                     mInnerFields.mDisplayHasContent = true;
                 }
@@ -9199,56 +9280,22 @@
                 continue;
             }
             final WindowStateAnimator winAnimator = win.mWinAnimator;
-            try {
-                if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
-                        "Reporting new frame to " + win + ": " + win.mCompatFrame);
-                int diff = 0;
-                boolean configChanged = win.isConfigChanged();
-                if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
-                        && configChanged) {
-                    Slog.i(TAG, "Sending new config to window " + win + ": "
-                            + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
-                            + " / " + mCurConfiguration + " / 0x"
-                            + Integer.toHexString(diff));
-                }
-                win.setConfiguration(mCurConfiguration);
-                if (DEBUG_ORIENTATION &&
-                        winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
-                        TAG, "Resizing " + win + " WITH DRAW PENDING");
-                final IWindow client = win.mClient;
-                final Rect frame = win.mFrame;
-                final Rect overscanInsets = win.mLastOverscanInsets;
-                final Rect contentInsets = win.mLastContentInsets;
-                final Rect visibleInsets = win.mLastVisibleInsets;
-                final boolean reportDraw
-                        = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
-                final Configuration newConfig = configChanged ? win.mConfiguration : null;
-                if (win.mClient instanceof IWindow.Stub) {
-                    // To prevent deadlock simulate one-way call if win.mClient is a local object.
-                    mH.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            try {
-                                client.resized(frame, overscanInsets, contentInsets,
-                                        visibleInsets, reportDraw, newConfig);
-                            } catch (RemoteException e) {
-                                // Not a remote call, RemoteException won't be raised.
-                            }
-                        }
-                    });
-                } else {
-                   client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
-                           newConfig);
-                }
-                win.mOverscanInsetsChanged = false;
-                win.mContentInsetsChanged = false;
-                win.mVisibleInsetsChanged = false;
-                winAnimator.mSurfaceResized = false;
-            } catch (RemoteException e) {
-                win.mOrientationChanging = false;
-                win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
-                        - mDisplayFreezeTime);
+            if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
+                    "Reporting new frame to " + win + ": " + win.mCompatFrame);
+            int diff = 0;
+            boolean configChanged = win.isConfigChanged();
+            if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
+                    && configChanged) {
+                Slog.i(TAG, "Sending new config to window " + win + ": "
+                        + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
+                        + " / " + mCurConfiguration + " / 0x"
+                        + Integer.toHexString(diff));
             }
+            win.setConfiguration(mCurConfiguration);
+            if (DEBUG_ORIENTATION &&
+                    winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
+                    TAG, "Resizing " + win + " WITH DRAW PENDING");
+            win.reportResized();
             mResizingWindows.remove(i);
         }
 
@@ -9309,10 +9356,7 @@
                     token.mAppAnimator.animating = false;
                     if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                             "performLayout: App token exiting now removed" + token);
-                    final Task task = mTaskIdToTask.get(token.groupId);
-                    if (task != null && task.removeAppToken(token)) {
-                        mTaskIdToTask.delete(token.groupId);
-                    }
+                    removeAppFromTask(token);
                     exitingAppTokens.remove(i);
                 }
             }
@@ -9393,8 +9437,9 @@
             for (i = 0; i < N; i++) {
                 WindowState w = mPendingRemoveTmp[i];
                 removeWindowInnerLocked(w.mSession, w);
-                if (!displayList.contains(w.mDisplayContent)) {
-                    displayList.add(w.mDisplayContent);
+                final DisplayContent displayContent = w.getDisplayContent();
+                if (displayContent != null && !displayList.contains(displayContent)) {
+                    displayList.add(displayContent);
                 }
             }
 
@@ -10765,7 +10810,6 @@
         return displayContent != null ? displayContent.getWindowList() : null;
     }
 
-    @Override
     public void onDisplayAdded(int displayId) {
         mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
     }
@@ -10780,7 +10824,6 @@
         }
     }
 
-    @Override
     public void onDisplayRemoved(int displayId) {
         mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
     }
@@ -10793,16 +10836,10 @@
             if (displayId == Display.DEFAULT_DISPLAY) {
                 unregisterPointerEventListener(displayContent.mTapDetector);
             }
-            WindowList windows = displayContent.getWindowList();
-            while (!windows.isEmpty()) {
-                final WindowState win = windows.get(windows.size() - 1);
-                removeWindowLocked(win.mSession, win);
-            }
         }
         mAnimator.removeDisplayLocked(displayId);
     }
 
-    @Override
     public void onDisplayChanged(int displayId) {
         mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 77a36b8..2f778b1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -29,7 +29,9 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import android.app.AppOpsManager;
+import android.os.Debug;
 import android.os.RemoteCallbackList;
+import android.os.SystemClock;
 import android.util.TimeUtils;
 import android.view.IWindowFocusObserver;
 import android.view.IWindowId;
@@ -593,9 +595,12 @@
         }
 
         if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) {
-            final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
-            mService.updateWallpaperOffsetLocked(this,
-                    displayInfo.logicalWidth, displayInfo.logicalHeight, false);
+            final DisplayContent displayContent = getDisplayContent();
+            if (displayContent != null) {
+                final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+                mService.updateWallpaperOffsetLocked(this,
+                        displayInfo.logicalWidth, displayInfo.logicalHeight, false);
+            }
         }
 
         if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG,
@@ -708,8 +713,16 @@
         return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged;
     }
 
+    public DisplayContent getDisplayContent() {
+        return mAppToken == null ? mDisplayContent : getStack().getDisplayContent();
+    }
+
     public int getDisplayId() {
-        return mDisplayContent.getDisplayId();
+        final DisplayContent displayContent = getDisplayContent();
+        if (displayContent == null) {
+            return -1;
+        }
+        return displayContent.getDisplayId();
     }
 
     TaskStack getStack() {
@@ -722,7 +735,8 @@
                 }
                 Slog.e(TAG, "getStack: mStack null for task=" + task);
             } else {
-                Slog.e(TAG, "getStack: couldn't find taskId=" + wtoken.groupId);
+                Slog.e(TAG, "getStack: " + this + " couldn't find taskId=" + wtoken.groupId
+                    + " Callers=" + Debug.getCallers(4));
             }
         }
         return mDisplayContent.getHomeStack();
@@ -1196,7 +1210,12 @@
 
     @Override
     public boolean isDefaultDisplay() {
-        return mDisplayContent.isDefaultDisplay;
+        final DisplayContent displayContent = getDisplayContent();
+        if (displayContent == null) {
+            // Only a window that was on a non-default display can be detached from it.
+            return false;
+        }
+        return getDisplayContent().isDefaultDisplay;
     }
 
     public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
@@ -1213,7 +1232,11 @@
                 && win.mAppToken != null && win.mAppToken.showWhenLocked) {
             // Save some cycles by not calling getDisplayInfo unless it is an application
             // window intended for all users.
-            final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo();
+            final DisplayContent displayContent = win.getDisplayContent();
+            if (displayContent == null) {
+                return true;
+            }
+            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
             if (win.mFrame.left <= 0 && win.mFrame.top <= 0
                     && win.mFrame.right >= displayInfo.appWidth
                     && win.mFrame.bottom >= displayInfo.appHeight) {
@@ -1255,7 +1278,8 @@
     }
 
     WindowList getWindowList() {
-        return mDisplayContent.getWindowList();
+        final DisplayContent displayContent = getDisplayContent();
+        return displayContent == null ? null : displayContent.getWindowList();
     }
 
     /**
@@ -1284,6 +1308,43 @@
         }
     }
 
+    void reportResized() {
+        try {
+            final Rect frame = mFrame;
+            final Rect overscanInsets = mLastOverscanInsets;
+            final Rect contentInsets = mLastContentInsets;
+            final Rect visibleInsets = mLastVisibleInsets;
+            final boolean reportDraw
+                    = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
+            final Configuration newConfig = isConfigChanged() ? mConfiguration : null;
+            if (mClient instanceof IWindow.Stub) {
+                // To prevent deadlock simulate one-way call if win.mClient is a local object.
+                mService.mH.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            mClient.resized(frame, overscanInsets, contentInsets,
+                                    visibleInsets, reportDraw, newConfig);
+                        } catch (RemoteException e) {
+                            // Not a remote call, RemoteException won't be raised.
+                        }
+                    }
+                });
+            } else {
+                mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
+                        newConfig);
+            }
+            mOverscanInsetsChanged = false;
+            mContentInsetsChanged = false;
+            mVisibleInsetsChanged = false;
+            mWinAnimator.mSurfaceResized = false;
+        } catch (RemoteException e) {
+            mOrientationChanging = false;
+            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                    - mService.mDisplayFreezeTime);
+        }
+    }
+
     public void registerFocusObserver(IWindowFocusObserver observer) {
         synchronized(mService.mWindowMap) {
             if (mFocusCallbacks == null) {
@@ -1308,7 +1369,7 @@
     }
 
     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
-        pw.print(prefix); pw.print("mDisplayId="); pw.print(mDisplayContent.getDisplayId());
+        pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
                 pw.print(" mSession="); pw.print(mSession);
                 pw.print(" mClient="); pw.println(mClient.asBinder());
         pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c405170..76e885f 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -150,8 +150,6 @@
     int mAttrFlags;
     int mAttrType;
 
-    final int mLayerStack;
-
     public WindowStateAnimator(final WindowState win) {
         final WindowManagerService service = win.mService;
 
@@ -159,7 +157,7 @@
         mAnimator = service.mAnimator;
         mPolicy = service.mPolicy;
         mContext = service.mContext;
-        final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo();
+        final DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo();
         mAnimDw = displayInfo.appWidth;
         mAnimDh = displayInfo.appHeight;
 
@@ -171,7 +169,6 @@
         mAttrFlags = win.mAttrs.flags;
         mAttrType = win.mAttrs.type;
         mIsWallpaper = win.mIsWallpaper;
-        mLayerStack = win.mDisplayContent.getDisplay().getLayerStack();
     }
 
     public void setAnimation(Animation anim) {
@@ -243,7 +240,8 @@
         // Save the animation state as it was before this step so WindowManagerService can tell if
         // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
         mWasAnimating = mAnimating;
-        if (mService.okToDisplay()) {
+        final DisplayContent displayContent = mWin.getDisplayContent();
+        if (displayContent != null && mService.okToDisplay()) {
             // We will run animations as long as the display isn't frozen.
 
             if (mWin.isDrawnLw() && mAnimation != null) {
@@ -258,7 +256,7 @@
                         " scale=" + mService.mWindowAnimationScale);
                     mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
                             mAnimDw, mAnimDh);
-                    final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo();
+                    final DisplayInfo displayInfo = displayContent.getDisplayInfo();
                     mAnimDw = displayInfo.appWidth;
                     mAnimDh = displayInfo.appHeight;
                     mAnimation.setStartTime(currentTime);
@@ -337,7 +335,9 @@
                         + mWin.mPolicyVisibilityAfterAnim);
             }
             mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
-            mWin.mDisplayContent.layoutNeeded = true;
+            if (displayContent != null) {
+                displayContent.layoutNeeded = true;
+            }
             if (!mWin.mPolicyVisibility) {
                 if (mService.mCurrentFocus == mWin) {
                     if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG,
@@ -363,11 +363,13 @@
         } else if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
             // Upon completion of a not-visible to visible status bar animation a relayout is
             // required.
-            mWin.mDisplayContent.layoutNeeded = true;
+            if (displayContent != null) {
+                displayContent.layoutNeeded = true;
+            }
         }
 
         finishExit();
-        final int displayId = mWin.mDisplayContent.getDisplayId();
+        final int displayId = mWin.getDisplayId();
         mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
                 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
@@ -732,7 +734,10 @@
                     mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
                     mSurfaceControl.setPosition(mSurfaceX, mSurfaceY);
                     mSurfaceLayer = mAnimLayer;
-                    mSurfaceControl.setLayerStack(mLayerStack);
+                    final DisplayContent displayContent = mWin.getDisplayContent();
+                    if (displayContent != null) {
+                        mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
+                    }
                     mSurfaceControl.setLayer(mAnimLayer);
                     mSurfaceControl.setAlpha(0);
                     mSurfaceShown = false;
@@ -921,8 +926,7 @@
                 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
             }
             //TODO (multidisplay): Magnification is supported only for the default display.
-            if (mService.mDisplayMagnifier != null
-                    && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
+            if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {
                 MagnificationSpec spec = mService.mDisplayMagnifier
                         .getMagnificationSpecForWindowLocked(mWin);
                 if (spec != null && !spec.isNop()) {
@@ -1002,7 +1006,7 @@
                 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);
         MagnificationSpec spec = null;
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mService.mDisplayMagnifier != null && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
+        if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {
             spec = mService.mDisplayMagnifier.getMagnificationSpecForWindowLocked(mWin);
         }
         if (applyUniverseTransformation || spec != null) {
@@ -1080,7 +1084,11 @@
 
     void updateSurfaceWindowCrop(final boolean recoveringMemory) {
         final WindowState w = mWin;
-        DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo();
+        final DisplayContent displayContent = w.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
 
         // Need to recompute a new system decor rect each time.
         if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
@@ -1181,8 +1189,7 @@
                         "SIZE " + width + "x" + height, null);
                 mSurfaceResized = true;
                 mSurfaceControl.setSize(width, height);
-                final int displayId = w.mDisplayContent.getDisplayId();
-                mAnimator.setPendingLayoutChanges(displayId,
+                mAnimator.setPendingLayoutChanges(w.getDisplayId(),
                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
                     w.getStack().startDimmingIfNeeded(this);
@@ -1444,7 +1451,10 @@
                         // do a layout.  If called from within the transaction
                         // loop, this will cause it to restart with a new
                         // layout.
-                        c.mDisplayContent.layoutNeeded = true;
+                        final DisplayContent displayContent = c.getDisplayContent();
+                        if (displayContent != null) {
+                            displayContent.layoutNeeded = true;
+                        }
                     }
                 }
             }
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index bfa0942..b5e4eef 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -76,7 +76,7 @@
         return mRegistered;
     }
     /** @hide */
-    public void setRegisterd(boolean registered) {
+    public void setRegistered(boolean registered) {
         mRegistered = registered;
     }
 
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 022bf12..d34c55c 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -275,7 +275,7 @@
      * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code>
      *   means the value is currently unknown and the system should wait until
      *   <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before
-     *   making the decisision to perform OTASP or not.
+     *   making the decision to perform OTASP or not.
      *
      * @hide
      */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a785bac..3d416fb 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,7 +23,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
-import android.telephony.Rlog;
 
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
@@ -433,7 +432,7 @@
         case RILConstants.NETWORK_MODE_GSM_UMTS:
         case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
         case RILConstants.NETWORK_MODE_LTE_WCDMA:
-        case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_GSM;
 
         // Use CDMA Phone for the global mode including CDMA
@@ -1258,7 +1257,7 @@
      * At registration, and when a specified telephony state
      * changes, the telephony manager invokes the appropriate
      * callback method on the listener object and passes the
-     * current (udpated) values.
+     * current (updated) values.
      * <p>
      * To unregister a listener, pass the listener object and set the
      * events argument to
@@ -1480,7 +1479,7 @@
      *
      * Input parameters equivalent to TS 27.007 AT+CGLA command.
      *
-     * @param channel is the channel id to be closed as retruned by a successful
+     * @param channel is the channel id to be closed as returned by a successful
      *            iccOpenLogicalChannel.
      * @param cla Class of the APDU command.
      * @param instruction Instruction of the APDU command.
@@ -1502,4 +1501,102 @@
         }
         return "";
     }
+
+    /**
+     * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @return the NV item as a String, or null on any failure.
+     * @hide
+     */
+    public String nvReadItem(int itemID) {
+        try {
+            return getITelephony().nvReadItem(itemID);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvReadItem RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvReadItem NPE", ex);
+        }
+        return "";
+    }
+
+
+    /**
+     * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @param itemValue the value to write, as a String.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean nvWriteItem(int itemID, String itemValue) {
+        try {
+            return getITelephony().nvWriteItem(itemID, itemValue);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvWriteItem RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvWriteItem NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param preferredRoamingList byte array containing the new PRL.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
+        try {
+            return getITelephony().nvWriteCdmaPrl(preferredRoamingList);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvWriteCdmaPrl RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvWriteCdmaPrl NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Perform the specified type of NV config reset.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset).
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean nvResetConfig(int resetType) {
+        try {
+            return getITelephony().nvResetConfig(resetType);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvResetConfig RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvResetConfig NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Change the radio to the specified mode.
+     * Used for device configuration by some operators.
+     *
+     * @param radioMode is 0 for offline mode, 1 for online mode, 2 for low-power mode,
+     *                  or 3 to reset the radio.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean setRadioMode(int radioMode) {
+        try {
+            return getITelephony().setRadioMode(radioMode);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setRadioMode RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "setRadioMode NPE", ex);
+        }
+        return false;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d9e9d56..370e27a 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -365,4 +365,51 @@
      */
     String iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
             int p1, int p2, int p3, String data);
+
+    /**
+     * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @return the NV item as a String, or null on any failure.
+     */
+    String nvReadItem(int itemID);
+
+    /**
+     * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @param itemValue the value to write, as a String.
+     * @return true on success; false on any failure.
+     */
+    boolean nvWriteItem(int itemID, String itemValue);
+
+    /**
+     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param preferredRoamingList byte array containing the new PRL.
+     * @return true on success; false on any failure.
+     */
+    boolean nvWriteCdmaPrl(in byte[] preferredRoamingList);
+
+    /**
+     * Perform the specified type of NV config reset.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset).
+     * @return true on success; false on any failure.
+     */
+    boolean nvResetConfig(int resetType);
+
+    /**
+     * Change the radio to the specified mode.
+     * Used for device configuration by some operators.
+     *
+     * @param radioMode is 0 for offline mode, 1 for online mode, 2 for low-power mode,
+     *                  or 3 to reset the radio.
+     * @return true on success; false on any failure.
+     */
+    boolean setRadioMode(int radioMode);
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 4163255..fc6c997 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -63,11 +63,11 @@
     public static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE;
     public static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE;
 
-    // Number presentation type for caller id display (From internal/Conneciton.java)
-    public static int PRESENTATION_ALLOWED = 1;    // normal
-    public static int PRESENTATION_RESTRICTED = 2; // block by user
-    public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
-    public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
+    // Number presentation type for caller id display (From internal/Connection.java)
+    public static final int PRESENTATION_ALLOWED = 1;    // normal
+    public static final int PRESENTATION_RESTRICTED = 2; // block by user
+    public static final int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
+    public static final int PRESENTATION_PAYPHONE = 4;   // show pay phone info
 
 
     public static final String PHONE_NAME_KEY = "phoneName";
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 8e445d9..6015df0 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -72,7 +72,7 @@
                                             AVAILABLE Application Settings menu*/
     int NETWORK_MODE_LTE_CDMA_EVDO  = 8; /* LTE, CDMA and EvDo */
     int NETWORK_MODE_LTE_GSM_WCDMA  = 9; /* LTE, GSM/WCDMA */
-    int NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
+    int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
     int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
     int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
     int PREFERRED_NETWORK_MODE      = NETWORK_MODE_WCDMA_PREF;
@@ -114,6 +114,10 @@
     int DEACTIVATE_REASON_RADIO_OFF = 1;
     int DEACTIVATE_REASON_PDP_RESET = 2;
 
+    /* NV config radio reset types. */
+    int NV_CONFIG_RESET_FACTORY = 1;
+    int NV_CONFIG_RESET_NV_ONLY = 2;
+
 /*
 cat include/telephony/ril.h | \
    egrep '^#define' | \
@@ -271,6 +275,12 @@
     int RIL_REQUEST_SIM_OPEN_CHANNEL = 115;
     int RIL_REQUEST_SIM_CLOSE_CHANNEL = 116;
     int RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117;
+    int RIL_REQUEST_NV_READ_ITEM = 118;
+    int RIL_REQUEST_NV_WRITE_ITEM = 119;
+    int RIL_REQUEST_NV_WRITE_CDMA_PRL = 120;
+    int RIL_REQUEST_NV_RESET_CONFIG = 121;
+    int RIL_REQUEST_SET_RADIO_MODE = 122;
+
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index a7baf1c..9ad2d42 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -125,16 +125,14 @@
      * Broadcast Action: The data connection state has changed for any one of the
      * phone's mobile data connections (eg, default, MMS or GPS specific connection).
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>phoneName</em> - A string version of the phone name.</li>
-     *   <li><em>state</em> - One of <code>"CONNECTED"</code>
-     *      <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li>
-     *   <li><em>apn</em> - A string that is the APN associated with this
-     *      connection.</li>
-     *   <li><em>apnType</em> - A string array of APN types associated with
-     *      this connection.  The APN type <code>"*"</code> is a special
-     *      type that means this APN services all types.</li>
-     * </ul>
+     * <dl>
+     *   <dt>phoneName</dt><dd>A string version of the phone name.</dd>
+     *   <dt>state</dt><dd>One of {@code CONNECTED}, {@code CONNECTING},
+     *      or {@code DISCONNECTED}.</dd>
+     *   <dt>apn</dt><dd>A string that is the APN associated with this connection.</dd>
+     *   <dt>apnType</dt><dd>A string array of APN types associated with this connection.
+     *      The APN type {@code *} is a special type that means this APN services all types.</dd>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -149,16 +147,14 @@
      * Broadcast Action: Occurs when a data connection connects to a provisioning apn
      * and is broadcast by the low level data connection code.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>apn</em> - A string that is the APN associated with this
-     *      connection.</li>
-     *   <li><em>apnType</em> - A string array of APN types associated with
-     *      this connection.  The APN type <code>"*"</code> is a special
-     *      type that means this APN services all types.</li>
-     *   <li><em>linkProperties</em> - The <code>LinkProperties</code> for this APN</li>
-     *   <li><em>linkCapabilities</em> - The <code>linkCapabilities</code> for this APN</li>
-     *   <li><em>iface</em> - A string that is the name of the interface</li>
-     * </ul>
+     * <dl>
+     *   <dt>apn</dt><dd>A string that is the APN associated with this connection.</dd>
+     *   <dt>apnType</dt><dd>A string array of APN types associated with this connection.
+     *      The APN type {@code *} is a special type that means this APN services all types.</dd>
+     *   <dt>linkProperties</dt><dd>{@code LinkProperties} for this APN.</dd>
+     *   <dt>linkCapabilities</dt><dd>The {@code LinkCapabilities} for this APN.</dd>
+     *   <dt>iface</dt><dd>A string that is the name of the interface.</dd>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -172,12 +168,11 @@
     /**
      * Broadcast Action: An attempt to establish a data connection has failed.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>phoneName</em> &mdash A string version of the phone name.</li>
-     *   <li><em>state</em> &mdash; One of <code>"CONNECTED"</code>
-     *      <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li>
-     * <li><em>reason</em> &mdash; A string indicating the reason for the failure, if available</li>
-     * </ul>
+     * <dl>
+     *   <dt>phoneName</dt><dd>A string version of the phone name.</dd>
+     *   <dt>state</dt><dd>One of {@code CONNECTED}, {@code CONNECTING}, or {code DISCONNECTED}.</dd>
+     *   <dt>reason</dt><dd>A string indicating the reason for the failure, if available.</dd>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -192,16 +187,23 @@
     /**
      * Broadcast Action: The sim card state has changed.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>phoneName</em> - A string version of the phone name.</li>
-     *   <li><em>ss</em> - The sim state.  One of
-     *   <code>"ABSENT"</code> <code>"LOCKED"</code>
-     *   <code>"READY"</code> <code>"ISMI"</code> <code>"LOADED"</code> </li>
-     *   <li><em>reason</em> - The reason while ss is LOCKED, otherwise is null
-     *   <code>"PIN"</code> locked on PIN1
-     *   <code>"PUK"</code> locked on PUK1
-     *   <code>"NETWORK"</code> locked on Network Personalization </li>
-     * </ul>
+     * <dl>
+     *   <dt>phoneName</dt><dd>A string version of the phone name.</dd>
+     *   <dt>ss</dt><dd>The sim state. One of:
+     *     <dl>
+     *       <dt>{@code ABSENT}</dt><dd>SIM card not found</dd>
+     *       <dt>{@code LOCKED}</dt><dd>SIM card locked (see {@code reason})</dd>
+     *       <dt>{@code READY}</dt><dd>SIM card ready</dd>
+     *       <dt>{@code IMSI}</dt><dd>FIXME: what is this state?</dd>
+     *       <dt>{@code LOADED}</dt><dd>SIM card data loaded</dd>
+     *     </dl></dd>
+     *   <dt>reason</dt><dd>The reason why ss is {@code LOCKED}; null otherwise.</dd>
+     *   <dl>
+     *       <dt>{@code PIN}</dt><dd>locked on PIN1</dd>
+     *       <dt>{@code PUK}</dt><dd>locked on PUK1</dd>
+     *       <dt>{@code NETWORK}</dt><dd>locked on network personalization</dd>
+     *   </dl>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -272,31 +274,30 @@
     /**
      * A <em>prefix</em> for the MCC/MNC filtering used with {@link #ACTION_CARRIER_SETUP}.
      * The MCC/MNC will be concatenated (zero-padded to 3 digits each) to create a final
-     * string of the form:
-     * <br />
-     * <code>android.intent.category.MCCMNC_310260</code>
+     * string of the form: {@code android.intent.category.MCCMNC_310260}
      */
     public static final String CATEGORY_MCCMNC_PREFIX = "android.intent.category.MCCMNC_";
 
     /**
      * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
-     * of the form *#*#<code>#*#*. The intent will have the data URI:</p>
+     * of the form {@code *#*#<code>#*#*}. The intent will have the data URI:
      *
-     * <p><code>android_secret_code://&lt;code&gt;</code></p>
+     * {@code android_secret_code://<code>}
      */
-    public static final String SECRET_CODE_ACTION =
-            "android.provider.Telephony.SECRET_CODE";
+    public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
 
     /**
      * Broadcast Action: The Service Provider string(s) have been updated.  Activities or
      * services that use these strings should update their display.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>showPlmn</em> - Boolean that indicates whether the PLMN should be shown.</li>
-     *   <li><em>plmn</em> - The operator name of the registered network, as a string.</li>
-     *   <li><em>showSpn</em> - Boolean that indicates whether the SPN should be shown.</li>
-     *   <li><em>spn</em> - The service provider name, as a string.</li>
-     * </ul>
+     *
+     * <dl>
+     *   <dt>showPlmn</dt><dd>Boolean that indicates whether the PLMN should be shown.</dd>
+     *   <dt>plmn</dt><dd>The operator name of the registered network, as a string.</dd>
+     *   <dt>showSpn</dt><dd>Boolean that indicates whether the SPN should be shown.</dd>
+     *   <dt>spn</dt><dd>The service provider name, as a string.</dd>
+     * </dl>
+     *
      * Note that <em>showPlmn</em> may indicate that <em>plmn</em> should be displayed, even
      * though the value for <em>plmn</em> is null.  This can happen, for example, if the phone
      * has not registered to a network yet.  In this case the receiver may substitute an
@@ -305,8 +306,7 @@
      * It is recommended to display <em>plmn</em> before / above <em>spn</em> if
      * both are displayed.
      *
-     * <p>Note this is a protected intent that can only be sent
-     * by the system.
+     * <p>Note: this is a protected intent that can only be sent by the system.
      */
     public static final String SPN_STRINGS_UPDATED_ACTION =
             "android.provider.Telephony.SPN_STRINGS_UPDATED";
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index e412c27..6a3c506 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1631,9 +1631,18 @@
 // =========================================================================
 // =========================================================================
 
-status_t AaptGroup::addFile(const sp<AaptFile>& file)
+status_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate)
 {
-    if (mFiles.indexOfKey(file->getGroupEntry()) < 0) {
+    ssize_t index = mFiles.indexOfKey(file->getGroupEntry());
+    if (index >= 0 && overwriteDuplicate) {
+        fprintf(stderr, "warning: overwriting '%s' with '%s'\n",
+                mFiles[index]->getSourceFile().string(),
+                file->getSourceFile().string());
+        removeFile(index);
+        index = -1;
+    }
+
+    if (index < 0) {
         file->mPath = mPath;
         mFiles.add(file->getGroupEntry(), file);
         return NO_ERROR;
@@ -1739,7 +1748,8 @@
     mDirs.removeItem(name);
 }
 
-status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file)
+status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file,
+        const bool overwrite)
 {
     sp<AaptGroup> group;
     if (mFiles.indexOfKey(leafName) >= 0) {
@@ -1749,12 +1759,12 @@
         mFiles.add(leafName, group);
     }
 
-    return group->addFile(file);
+    return group->addFile(file, overwrite);
 }
 
 ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
                             const AaptGroupEntry& kind, const String8& resType,
-                            sp<FilePathStore>& fullResPaths)
+                            sp<FilePathStore>& fullResPaths, const bool overwrite)
 {
     Vector<String8> fileNames;
     {
@@ -1813,7 +1823,7 @@
                 notAdded = true;
             }
             ssize_t res = subdir->slurpFullTree(bundle, pathName, kind,
-                                                resType, fullResPaths);
+                                                resType, fullResPaths, overwrite);
             if (res < NO_ERROR) {
                 return res;
             }
@@ -1823,7 +1833,7 @@
             count += res;
         } else if (type == kFileTypeRegular) {
             sp<AaptFile> file = new AaptFile(pathName, kind, resType);
-            status_t err = addLeafFile(fileNames[i], file);
+            status_t err = addLeafFile(fileNames[i], file, overwrite);
             if (err != NO_ERROR) {
                 return err;
             }
@@ -2089,24 +2099,24 @@
     /*
      * If a directory of custom assets was supplied, slurp 'em up.
      */
-    if (bundle->getAssetSourceDir()) {
-        const char* assetDir = bundle->getAssetSourceDir();
-
-        FileType type = getFileType(assetDir);
+    const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs();
+    const int AN = assetDirs.size();
+    for (int i = 0; i < AN; i++) {
+        FileType type = getFileType(assetDirs[i]);
         if (type == kFileTypeNonexistent) {
-            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDir);
+            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDirs[i]);
             return UNKNOWN_ERROR;
         }
         if (type != kFileTypeDirectory) {
-            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir);
+            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDirs[i]);
             return UNKNOWN_ERROR;
         }
 
-        String8 assetRoot(assetDir);
+        String8 assetRoot(assetDirs[i]);
         sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));
         AaptGroupEntry group;
         count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,
-                                            String8(), mFullAssetPaths);
+                                            String8(), mFullAssetPaths, true);
         if (count < 0) {
             totalCount = count;
             goto bail;
@@ -2116,9 +2126,10 @@
         }
         totalCount += count;
 
-        if (bundle->getVerbose())
+        if (bundle->getVerbose()) {
             printf("Found %d custom asset file%s in %s\n",
-                   count, (count==1) ? "" : "s", assetDir);
+                   count, (count==1) ? "" : "s", assetDirs[i]);
+        }
     }
 
     /*
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 5cfa913..9cc9007 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -235,7 +235,7 @@
     const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const
         { return mFiles; }
 
-    status_t addFile(const sp<AaptFile>& file);
+    status_t addFile(const sp<AaptFile>& file, const bool overwriteDuplicate=false);
     void removeFile(size_t index);
 
     void print(const String8& prefix) const;
@@ -301,12 +301,14 @@
     status_t addDir(const String8& name, const sp<AaptDir>& dir);
     sp<AaptDir> makeDir(const String8& name);
     status_t addLeafFile(const String8& leafName,
-                         const sp<AaptFile>& file);
+                         const sp<AaptFile>& file,
+                         const bool overwrite=false);
     virtual ssize_t slurpFullTree(Bundle* bundle,
                                   const String8& srcDir,
                                   const AaptGroupEntry& kind,
                                   const String8& resType,
-                                  sp<FilePathStore>& fullResPaths);
+                                  sp<FilePathStore>& fullResPaths,
+                                  const bool overwrite=false);
 
     String8 mLeaf;
     String8 mPath;
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 52d9266..cbeaae8 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -55,7 +55,6 @@
           mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
           mAutoAddOverlay(false), mGenDependencies(false),
-          mAssetSourceDir(NULL),
           mCrunchedOutputDir(NULL), mProguardFile(NULL),
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
@@ -128,8 +127,8 @@
     /*
      * Input options.
      */
-    const char* getAssetSourceDir() const { return mAssetSourceDir; }
-    void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; }
+    const android::Vector<const char*>& getAssetSourceDirs() const { return mAssetSourceDirs; }
+    void addAssetSourceDir(const char* dir) { mAssetSourceDirs.insertAt(dir,0); }
     const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }
     void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }
     const char* getProguardFile() const { return mProguardFile; }
@@ -266,7 +265,6 @@
     const char* mInstrumentationPackageNameOverride;
     bool        mAutoAddOverlay;
     bool        mGenDependencies;
-    const char* mAssetSourceDir;
     const char* mCrunchedOutputDir;
     const char* mProguardFile;
     const char* mAndroidManifestFile;
@@ -278,6 +276,7 @@
     android::Vector<const char*> mPackageIncludes;
     android::Vector<const char*> mJarFiles;
     android::Vector<const char*> mNoCompressExtensions;
+    android::Vector<const char*> mAssetSourceDirs;
     android::Vector<const char*> mResourceSourceDirs;
 
     const char* mManifestMinSdkVersion;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index c527388..48e3125 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -2034,7 +2034,7 @@
 
     N = bundle->getFileSpecCount();
     if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0
-            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) {
+            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) {
         fprintf(stderr, "ERROR: no input files\n");
         goto bail;
     }
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 51a1248..1ed4630 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -349,7 +349,7 @@
                     goto bail;
                 }
                 convertPath(argv[0]);
-                bundle.setAssetSourceDir(argv[0]);
+                bundle.addAssetSourceDir(argv[0]);
                 break;
             case 'G':
                 argc--;