Merge "Ignore certain WindowManager flags when touch exploration is enabled" into klp-dev
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 85fa7d6..4fe2c4d 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -487,6 +487,12 @@
      * Gain factor from electrons to raw units when
      * ISO=100
      * </p>
+     *
+     * <b>Optional</b> - This value may be null on some devices.
+     *
+     * <b>{@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL}</b> -
+     * Present on all devices that report being FULL level hardware devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL HARDWARE_LEVEL} key.
      */
     public static final Key<Rational> SENSOR_BASE_GAIN_FACTOR =
             new Key<Rational>("android.sensor.baseGainFactor", Rational.class);
@@ -502,6 +508,12 @@
      * values above this, it can be a mix of analog and
      * digital
      * </p>
+     *
+     * <b>Optional</b> - This value may be null on some devices.
+     *
+     * <b>{@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL}</b> -
+     * Present on all devices that report being FULL level hardware devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL HARDWARE_LEVEL} key.
      */
     public static final Key<Integer> SENSOR_MAX_ANALOG_SENSITIVITY =
             new Key<Integer>("android.sensor.maxAnalogSensitivity", int.class);
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 30bffc4..dbd0457 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -722,6 +722,12 @@
      * The thermal diode being queried should be inside the sensor PCB, or
      * somewhere close to it.
      * </p>
+     *
+     * <b>Optional</b> - This value may be null on some devices.
+     *
+     * <b>{@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL}</b> -
+     * Present on all devices that report being FULL level hardware devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL HARDWARE_LEVEL} key.
      */
     public static final Key<Float> SENSOR_TEMPERATURE =
             new Key<Float>("android.sensor.temperature", float.class);
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index eb82ed4..adccbc5 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -92,6 +92,15 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T get(Key<T> key) {
+
+        if (key == CaptureResult.STATISTICS_FACES) {
+            /**
+             * FIXME: Workaround for HAL bug that's missing FACE_DETECT_MODE
+             */
+            Log.w(TAG, "Expected non-null android.statistics.faceDetectMode");
+            return null;
+        }
+
         T value = getOverride(key);
         if (value != null) {
             return value;
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index ec979b3..e1a9cb7 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -282,7 +282,7 @@
          */
         public static final MediaSize UNKNOWN_PORTRAIT =
                 new MediaSize("UNKNOWN_PORTRAIT", "android",
-                        R.string.mediasize_unknown_portrait, Integer.MAX_VALUE, 1);
+                        R.string.mediasize_unknown_portrait, 1, Integer.MAX_VALUE);
 
         /**
          * Unknown media size in landscape mode.
@@ -293,7 +293,7 @@
          */
         public static final MediaSize UNKNOWN_LANDSCAPE =
                 new MediaSize("UNKNOWN_LANDSCAPE", "android",
-                        R.string.mediasize_unknown_landscape, 1, Integer.MAX_VALUE);
+                        R.string.mediasize_unknown_landscape, Integer.MAX_VALUE, 1);
 
         // ISO sizes
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 989e287..50777fd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2441,9 +2441,7 @@
             SCREEN_BRIGHTNESS_MODE,
             SCREEN_AUTO_BRIGHTNESS_ADJ,
             VIBRATE_INPUT_DEVICES,
-            MODE_RINGER,                // moved to global
             MODE_RINGER_STREAMS_AFFECTED,
-            MUTE_STREAMS_AFFECTED,
             VOLUME_VOICE,
             VOLUME_SYSTEM,
             VOLUME_RING,
@@ -5940,7 +5938,6 @@
         public static final String[] SETTINGS_TO_BACKUP = {
             BUGREPORT_IN_POWER_MENU,
             STAY_ON_WHILE_PLUGGED_IN,
-            MODE_RINGER,
             AUTO_TIME,
             AUTO_TIME_ZONE,
             POWER_SOUNDS_ENABLED,
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 3e53b91..9e35a23 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -27,6 +27,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.RectF;
+import android.graphics.Xfermode;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -73,6 +74,7 @@
 
     // these are applied to the drawable
     private ColorFilter mColorFilter;
+    private Xfermode mXfermode;
     private int mAlpha = 255;
     private int mViewAlphaScale = 256;
     private boolean mColorMod = false;
@@ -1125,6 +1127,18 @@
     }
 
     /**
+     * @hide Candidate for future API inclusion
+     */
+    public final void setXfermode(Xfermode mode) {
+        if (mXfermode != mode) {
+            mXfermode = mode;
+            mColorMod = true;
+            applyColorMod();
+            invalidate();
+        }
+    }
+
+    /**
      * Returns the active color filter for this ImageView.
      *
      * @return the active color filter for this ImageView
@@ -1200,6 +1214,7 @@
         if (mDrawable != null && mColorMod) {
             mDrawable = mDrawable.mutate();
             mDrawable.setColorFilter(mColorFilter);
+            mDrawable.setXfermode(mXfermode);
             mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
         }
     }
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 5ceab36..98e3386 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -28,6 +28,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.Shader;
+import android.graphics.Xfermode;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.LayoutDirection;
@@ -531,6 +532,14 @@
     }
 
     /**
+     * @hide Candidate for future API inclusion
+     */
+    public void setXfermode(Xfermode xfermode) {
+        mBitmapState.mPaint.setXfermode(xfermode);
+        invalidateSelf();
+    }
+
+    /**
      * A mutable BitmapDrawable still shares its Bitmap with any other Drawable
      * that comes from the same resource.
      *
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 8135716..8a3d940 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -17,6 +17,7 @@
 package android.graphics.drawable;
 
 import android.graphics.Insets;
+import android.graphics.Xfermode;
 import android.os.Trace;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -428,6 +429,15 @@
     public abstract void setColorFilter(ColorFilter cf);
 
     /**
+     * @hide Consider for future API inclusion
+     */
+    public void setXfermode(Xfermode mode) {
+        // Base implementation drops it on the floor for compatibility. Whee!
+        // TODO: For this to be included in the API proper, all framework drawables need impls.
+        // For right now only BitmapDrawable has it.
+    }
+
+    /**
      * Specify a color and porterduff mode to be the colorfilter for this
      * drawable.
      */
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index d185321..07d91ac 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -275,6 +275,13 @@
                                 // tell the RCCs about the change for this RCD
                                 enableRemoteControlDisplayForClient_syncRcStack(
                                         di.mRcDisplay, di.mEnabled);
+                                // when enabling, refresh the information on the display
+                                if (di.mEnabled) {
+                                    sendMsg(mEventHandler, MSG_RCDISPLAY_INIT_INFO, SENDMSG_QUEUE,
+                                            di.mArtworkExpectedWidth /*arg1*/,
+                                            di.mArtworkExpectedHeight/*arg2*/,
+                                            di.mRcDisplay /*obj*/, 0/*delay*/);
+                                }
                             } catch (RemoteException e) {
                                 Log.e(TAG, "Error en/disabling RCD: ", e);
                             }
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index c6d6296..32e85d9 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -784,8 +784,34 @@
     }
 
     private void onDisplayEnable(boolean enabled) {
+        final OnClientUpdateListener l;
         synchronized(mInfoLock) {
             mEnabled = enabled;
+            l = this.mOnClientUpdateListener;
+        }
+        if (!enabled) {
+            // when disabling, reset all info sent to the user
+            final int genId;
+            synchronized (mGenLock) {
+                genId = mClientGenerationIdCurrent;
+            }
+            // send "stopped" state, happened "now", playback position is 0, speed 0.0f
+            final PlaybackInfo pi = new PlaybackInfo(RemoteControlClient.PLAYSTATE_STOPPED,
+                    SystemClock.elapsedRealtime() /*stateChangeTimeMs*/,
+                    0 /*currentPosMs*/, 0.0f /*speed*/);
+            sendMsg(mEventHandler, MSG_NEW_PLAYBACK_INFO, SENDMSG_REPLACE,
+                    genId /*arg1*/, 0 /*arg2, ignored*/, pi /*obj*/, 0 /*delay*/);
+            // send "blank" transport control info: no controls are supported
+            sendMsg(mEventHandler, MSG_NEW_TRANSPORT_INFO, SENDMSG_REPLACE,
+                    genId /*arg1*/, 0 /*arg2, no flags*/,
+                    null /*obj, ignored*/, 0 /*delay*/);
+            // send dummy metadata with empty string for title and artist, duration of 0
+            Bundle metadata = new Bundle(3);
+            metadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE), "");
+            metadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST), "");
+            metadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION), 0);
+            sendMsg(mEventHandler, MSG_NEW_METADATA, SENDMSG_QUEUE,
+                    genId /*arg1*/, 0 /*arg2, ignored*/, metadata /*obj*/, 0 /*delay*/);
         }
     }
 
diff --git a/packages/Keyguard/res/drawable-hdpi/progress_bg_holo_light.9.png b/packages/Keyguard/res/drawable-hdpi/progress_bg_holo_light.9.png
new file mode 100644
index 0000000..2d79280
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/progress_bg_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/progress_primary_holo_light.9.png b/packages/Keyguard/res/drawable-hdpi/progress_primary_holo_light.9.png
new file mode 100644
index 0000000..543cb85
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/progress_secondary_holo_light.9.png b/packages/Keyguard/res/drawable-hdpi/progress_secondary_holo_light.9.png
new file mode 100644
index 0000000..4497058
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_control_disabled_holo.png b/packages/Keyguard/res/drawable-hdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..ba77899
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_control_focused_holo.png b/packages/Keyguard/res/drawable-hdpi/scrubber_control_focused_holo.png
new file mode 100644
index 0000000..539ee22
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_control_focused_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_control_normal_holo.png b/packages/Keyguard/res/drawable-hdpi/scrubber_control_normal_holo.png
new file mode 100644
index 0000000..9a4ea2f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_control_normal_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_control_pressed_holo.png b/packages/Keyguard/res/drawable-hdpi/scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..e6b11de
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_control_pressed_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_primary_holo.9.png b/packages/Keyguard/res/drawable-hdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..822e8d11
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_secondary_holo.9.png b/packages/Keyguard/res/drawable-hdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..be4253e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/scrubber_track_holo_light.9.png b/packages/Keyguard/res/drawable-hdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..2334e14
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/progress_bg_holo_light.9.png b/packages/Keyguard/res/drawable-mdpi/progress_bg_holo_light.9.png
new file mode 100644
index 0000000..ff40433
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/progress_bg_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/progress_primary_holo_light.9.png b/packages/Keyguard/res/drawable-mdpi/progress_primary_holo_light.9.png
new file mode 100644
index 0000000..d5f874d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/progress_secondary_holo_light.9.png b/packages/Keyguard/res/drawable-mdpi/progress_secondary_holo_light.9.png
new file mode 100644
index 0000000..f027007
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_control_disabled_holo.png b/packages/Keyguard/res/drawable-mdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..981facd
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_control_focused_holo.png b/packages/Keyguard/res/drawable-mdpi/scrubber_control_focused_holo.png
new file mode 100644
index 0000000..d432f42
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_control_focused_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_control_normal_holo.png b/packages/Keyguard/res/drawable-mdpi/scrubber_control_normal_holo.png
new file mode 100644
index 0000000..7bb749e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_control_normal_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_control_pressed_holo.png b/packages/Keyguard/res/drawable-mdpi/scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..43d826e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_control_pressed_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_primary_holo.9.png b/packages/Keyguard/res/drawable-mdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..98ac428
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_secondary_holo.9.png b/packages/Keyguard/res/drawable-mdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..d8b563b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/scrubber_track_holo_light.9.png b/packages/Keyguard/res/drawable-mdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..47c5dd9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/progress_bg_holo_light.9.png b/packages/Keyguard/res/drawable-xhdpi/progress_bg_holo_light.9.png
new file mode 100644
index 0000000..dff0939
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/progress_bg_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/progress_primary_holo_light.9.png b/packages/Keyguard/res/drawable-xhdpi/progress_primary_holo_light.9.png
new file mode 100644
index 0000000..60b8198
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/progress_secondary_holo_light.9.png b/packages/Keyguard/res/drawable-xhdpi/progress_secondary_holo_light.9.png
new file mode 100644
index 0000000..11b31be
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_control_disabled_holo.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..ffe913d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_control_focused_holo.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_focused_holo.png
new file mode 100644
index 0000000..2fccb8f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_focused_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_control_normal_holo.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_normal_holo.png
new file mode 100644
index 0000000..a638501
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_normal_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_control_pressed_holo.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..f0e65ea
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_control_pressed_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_primary_holo.9.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..04f6ae3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_secondary_holo.9.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..7fef98d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/scrubber_track_holo_light.9.png b/packages/Keyguard/res/drawable-xhdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..a712169
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-xxhdpi/kg_add_widget_pressed.png
new file mode 100644
index 0000000..0c0838b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/progress_bg_holo_light.9.png b/packages/Keyguard/res/drawable-xxhdpi/progress_bg_holo_light.9.png
new file mode 100644
index 0000000..60a8e22
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/progress_bg_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/progress_primary_holo_light.9.png b/packages/Keyguard/res/drawable-xxhdpi/progress_primary_holo_light.9.png
new file mode 100644
index 0000000..18384d3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/progress_secondary_holo_light.9.png b/packages/Keyguard/res/drawable-xxhdpi/progress_secondary_holo_light.9.png
new file mode 100644
index 0000000..82eb615
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_disabled_holo.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..d1ac7ae
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_focused_holo.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_focused_holo.png
new file mode 100644
index 0000000..58a2976
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_focused_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_normal_holo.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_normal_holo.png
new file mode 100644
index 0000000..6f696fd
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_normal_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_pressed_holo.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..faae4e3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_control_pressed_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_primary_holo.9.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..82c2b7e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_secondary_holo.9.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..800d95e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xxhdpi/scrubber_track_holo_light.9.png b/packages/Keyguard/res/drawable-xxhdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..9991f7f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xxhdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable/scrubber_control_selector_holo.xml b/packages/Keyguard/res/drawable/scrubber_control_selector_holo.xml
new file mode 100644
index 0000000..d09b1a5
--- /dev/null
+++ b/packages/Keyguard/res/drawable/scrubber_control_selector_holo.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:drawable="@drawable/scrubber_control_disabled_holo" />
+    <item android:state_pressed="true" android:drawable="@drawable/scrubber_control_pressed_holo" />
+    <item android:state_selected="true" android:drawable="@drawable/scrubber_control_focused_holo" />
+    <item android:drawable="@drawable/scrubber_control_normal_holo" />
+</selector>
diff --git a/packages/Keyguard/res/drawable/scrubber_progress_horizontal_holo_light.xml b/packages/Keyguard/res/drawable/scrubber_progress_horizontal_holo_light.xml
new file mode 100644
index 0000000..f07c742
--- /dev/null
+++ b/packages/Keyguard/res/drawable/scrubber_progress_horizontal_holo_light.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/background"
+            android:drawable="@drawable/scrubber_track_holo_light" />
+    <item android:id="@android:id/secondaryProgress">
+        <scale android:scaleWidth="100%"
+               android:drawable="@drawable/scrubber_secondary_holo" />
+    </item>
+    <item android:id="@android:id/progress">
+        <scale android:scaleWidth="100%"
+               android:drawable="@drawable/scrubber_primary_holo" />
+    </item>
+</layer-list>
diff --git a/packages/Keyguard/res/layout/keyguard_transport_control_view.xml b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
index 81c7425..a0b59a7 100644
--- a/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
@@ -75,7 +75,8 @@
                 <SeekBar
                     android:id="@+id/transient_seek_bar"
                     android:layout_width="match_parent"
-                    android:layout_height="wrap_content" />
+                    android:layout_height="wrap_content"
+                    style="@style/Widget.TransportControl.SeekBar" />
                 <TextView
                     android:id="@+id/transient_seek_time_elapsed"
                     android:layout_width="wrap_content"
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
index 3c004ce..01bf687 100644
--- a/packages/Keyguard/res/values-uk/strings.xml
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -73,7 +73,7 @@
     <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Кнопка \"Зупинити\""</string>
     <string name="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Подобається"</string>
     <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Не подобається"</string>
-    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Серце"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Рейтинг"</string>
     <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Розблокуйте, щоб продовжити"</string>
     <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Запуск скасовано"</string>
     <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Відпустіть <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>, щоб видалити."</string>
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
index 44f560f..9fd8f31 100644
--- a/packages/Keyguard/res/values/styles.xml
+++ b/packages/Keyguard/res/values/styles.xml
@@ -68,4 +68,18 @@
         <item name="android:textSize">@dimen/widget_big_font_size</item>
     </style>
 
+    <style name="Widget.TransportControl.SeekBar" parent="@android:style/Widget.Holo.SeekBar">
+        <item name="android:indeterminateOnly">false</item>
+        <item name="android:progressDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>
+        <item name="android:indeterminateDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>
+        <item name="android:minHeight">13dip</item>
+        <item name="android:maxHeight">13dip</item>
+        <item name="android:thumb">@drawable/scrubber_control_selector_holo</item>
+        <item name="android:thumbOffset">16dip</item>
+        <item name="android:focusable">true</item>
+        <item name="android:paddingStart">16dip</item>
+        <item name="android:paddingEnd">16dip</item>
+        <item name="android:mirrorForRtl">true</item>
+    </style>
+
 </resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
index 03b09b1..c33f174 100644
--- a/packages/Keyguard/src/com/android/keyguard/CarrierText.java
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -47,6 +47,14 @@
             mSimState = simState;
             updateCarrierText(mSimState, mPlmn, mSpn);
         }
+
+        public void onScreenTurnedOff(int why) {
+            setSelected(false);
+        };
+
+        public void onScreenTurnedOn() {
+            setSelected(true);
+        };
     };
     /**
      * The status of this lock screen. Primarily used for widgets on LockScreen.
@@ -79,7 +87,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mSeparator = getResources().getString(R.string.kg_text_message_separator);
-        setSelected(true); // Allow marquee to work.
+        final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+        setSelected(screenOn); // Allow marquee to work.
     }
 
     @Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index ad59c02..69075ec 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -163,6 +163,12 @@
             mBatteryIsLow = status.isBatteryLow();
             update();
         }
+        public void onScreenTurnedOff(int why) {
+            setSelected(false);
+        };
+        public void onScreenTurnedOn() {
+            setSelected(true);
+        };
     };
 
     public KeyguardMessageArea(Context context) {
@@ -174,9 +180,6 @@
 
         mLockPatternUtils = new LockPatternUtils(context);
 
-        // This is required to ensure marquee works
-        setSelected(true);
-
         // Registering this callback immediately updates the battery state, among other things.
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
         mUpdateMonitor.registerCallback(mInfoCallback);
@@ -187,6 +190,12 @@
         update();
     }
 
+    @Override
+    protected void onFinishInflate() {
+        final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+        setSelected(screenOn); // This is required to ensure marquee works
+    }
+
     public void securityMessageChanged() {
         setAlpha(1f);
         mShowingMessage = true;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index ffb619b..3e42c14 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -21,6 +21,7 @@
 import android.graphics.Typeface;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Slog;
 import android.view.View;
 import android.widget.GridLayout;
@@ -56,6 +57,14 @@
                 refresh();
             }
         };
+
+        public void onScreenTurnedOn() {
+            setEnableMarquee(true);
+        };
+
+        public void onScreenTurnedOff(int why) {
+            setEnableMarquee(false);
+        };
     };
 
     public KeyguardStatusView(Context context) {
@@ -70,22 +79,18 @@
         super(context, attrs, defStyle);
     }
 
+    private void setEnableMarquee(boolean enabled) {
+        if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
+        if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-
         mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
         mLockPatternUtils = new LockPatternUtils(getContext());
-
-        // Required to get Marquee to work.
-        final View marqueeViews[] = { mAlarmStatusView };
-        for (int i = 0; i < marqueeViews.length; i++) {
-            View v = marqueeViews[i];
-            if (v == null) {
-                throw new RuntimeException("Can't find widget at index " + i);
-            }
-            v.setSelected(true);
-        }
+        final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+        setEnableMarquee(screenOn);
         refresh();
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
index 6d7b743..ca4892d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
@@ -22,6 +22,8 @@
 import android.graphics.Bitmap;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.media.MediaMetadataEditor;
@@ -198,6 +200,16 @@
 
     KeyguardHostView.TransportControlCallback mTransportControlCallback;
 
+    private final KeyguardUpdateMonitorCallback mUpdateMonitor
+            = new KeyguardUpdateMonitorCallback() {
+        public void onScreenTurnedOff(int why) {
+            setEnableMarquee(false);
+        };
+        public void onScreenTurnedOn() {
+            setEnableMarquee(true);
+        };
+    };
+
     public KeyguardTransportControlView(Context context, AttributeSet attrs) {
         super(context, attrs);
         if (DEBUG) Log.v(TAG, "Create TCV " + this);
@@ -250,6 +262,12 @@
         mTransportControlCallback = transportControlCallback;
     }
 
+    private void setEnableMarquee(boolean enabled) {
+        if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
+        if (mTrackTitle != null) mTrackTitle.setSelected(enabled);
+        if (mTrackArtistAlbum != null) mTrackTitle.setSelected(enabled);
+    }
+
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
@@ -257,9 +275,7 @@
         mMetadataContainer = (ViewGroup) findViewById(R.id.metadata_container);
         mBadge = (ImageView) findViewById(R.id.badge);
         mTrackTitle = (TextView) findViewById(R.id.title);
-        mTrackTitle.setSelected(true); // enable marquee
         mTrackArtistAlbum = (TextView) findViewById(R.id.artist_album);
-        mTrackArtistAlbum.setSelected(true);
         mTransientSeek = findViewById(R.id.transient_seek);
         mTransientSeekBar = (SeekBar) findViewById(R.id.transient_seek_bar);
         mTransientSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
@@ -273,6 +289,8 @@
             view.setOnClickListener(mTransportCommandListener);
             view.setOnLongClickListener(mTransportShowSeekBarListener);
         }
+        final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+        setEnableMarquee(screenOn);
     }
 
     @Override
@@ -285,6 +303,7 @@
         }
         if (DEBUG) Log.v(TAG, "Registering TCV " + this);
         mAudioManager.registerRemoteController(mRemoteController);
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitor);
     }
 
     @Override
@@ -301,6 +320,7 @@
         super.onDetachedFromWindow();
         if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
         mAudioManager.unregisterRemoteController(mRemoteController);
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitor);
         mUserSeeking = false;
     }
 
@@ -310,6 +330,7 @@
         final ColorMatrix cm = new ColorMatrix();
         cm.setSaturation(0);
         mBadge.setColorFilter(new ColorMatrixColorFilter(cm));
+        mBadge.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
         mBadge.setImageAlpha(0xef);
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 76deb77..45cd3d4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -92,7 +92,8 @@
     protected static final int MSG_SET_PLAYBACK_STATE = 316;
     protected static final int MSG_USER_INFO_CHANGED = 317;
     protected static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
-
+    private static final int MSG_SCREEN_TURNED_ON = 319;
+    private static final int MSG_SCREEN_TURNED_OFF = 320;
 
     private static KeyguardUpdateMonitor sInstance;
 
@@ -127,6 +128,8 @@
 
     private boolean mSwitchingUser;
 
+    private boolean mScreenOn;
+
     private final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -185,6 +188,12 @@
                 case MSG_REPORT_EMERGENCY_CALL_ACTION:
                     handleReportEmergencyCallAction();
                     break;
+                case MSG_SCREEN_TURNED_OFF:
+                    handleScreenTurnedOff(msg.arg1);
+                    break;
+                case MSG_SCREEN_TURNED_ON:
+                    handleScreenTurnedOn();
+                    break;
             }
         }
     };
@@ -411,6 +420,26 @@
         return sInstance;
     }
 
+    protected void handleScreenTurnedOn() {
+        final int count = mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onScreenTurnedOn();
+            }
+        }
+    }
+
+    protected void handleScreenTurnedOff(int arg1) {
+        final int count = mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onScreenTurnedOff(arg1);
+            }
+        }
+    }
+
     /**
      * IMPORTANT: Must be called from UI thread.
      */
@@ -1041,4 +1070,24 @@
     public DisplayClientState getCachedDisplayClientState() {
         return mDisplayClientState;
     }
+
+    // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
+    // (KeyguardViewMediator, KeyguardHostView)
+    public void dispatchScreenTurnedOn() {
+        synchronized (this) {
+            mScreenOn = true;
+        }
+        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
+    }
+
+    public void dispatchScreenTurndOff(int why) {
+        synchronized(this) {
+            mScreenOn = false;
+        }
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_SCREEN_TURNED_OFF, why, 0));
+    }
+
+    public boolean isScreenOn() {
+        return mScreenOn;
+    }
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index e6dddab..76f9637 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -19,6 +19,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.graphics.Bitmap;
 import android.media.AudioManager;
+import android.view.WindowManagerPolicy;
 
 import com.android.internal.telephony.IccCardConstants;
 
@@ -137,7 +138,23 @@
      */
     void onEmergencyCallAction() { }
 
+    /**
+     * Called when the transport background changes.
+     * @param bitmap
+     */
     public void onSetBackground(Bitmap bitmap) {
-        // THIS SPACE FOR RENT
     }
+
+    /**
+     * Called when the screen turns on
+     */
+    public void onScreenTurnedOn() { }
+
+    /**
+     * Called when the screen turns off
+     * @param why {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
+     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
+     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
+     */
+    public void onScreenTurnedOff(int why) { }
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index dc28bd0..a37a3a4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -599,6 +599,7 @@
                 doKeyguardLocked(null);
             }
         }
+        KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why);
     }
 
     private void doKeyguardLaterLocked() {
@@ -664,6 +665,7 @@
                 notifyScreenOnLocked(callback);
             }
         }
+        KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurnedOn();
         maybeSendUserPresentBroadcast();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 09f1695..01c27f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -514,9 +514,13 @@
     private final void updateTelephonySignalStrength() {
         if (!hasService()) {
             if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
-            mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+            if (!mSimState.iccCardExist()) {
+                mPhoneSignalIconId = R.drawable.stat_sys_no_sim;
+            } else {
+                mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+            }
+            mDataSignalIconId = mPhoneSignalIconId;
             mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
-            mDataSignalIconId = R.drawable.stat_sys_signal_null;
         } else {
             if (mSignalStrength == null) {
                 if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
diff --git a/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml b/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml
index 6dc7e35..97d7001 100644
--- a/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml
+++ b/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml
@@ -19,7 +19,7 @@
 -->
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/wallpaper_cropper"
+    android:id="@+id/wallpaper_root"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
     <com.android.wallpapercropper.CropView
diff --git a/packages/WallpaperCropper/res/values-sw600dp/config.xml b/packages/WallpaperCropper/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..62342dc
--- /dev/null
+++ b/packages/WallpaperCropper/res/values-sw600dp/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+    <bool name="allow_rotation">true</bool>
+</resources>
diff --git a/packages/WallpaperCropper/res/values/config.xml b/packages/WallpaperCropper/res/values/config.xml
new file mode 100644
index 0000000..1b24190
--- /dev/null
+++ b/packages/WallpaperCropper/res/values/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+    <bool name="allow_rotation">false</bool>
+</resources>
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
index ecebd642..b4e715c 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
@@ -22,8 +22,8 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
-import android.view.ViewConfiguration;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
+import android.view.ViewConfiguration;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 
@@ -44,6 +44,7 @@
     public interface TouchCallback {
         void onTouchDown();
         void onTap();
+        void onTouchUp();
     }
 
     public CropView(Context context) {
@@ -140,12 +141,12 @@
     public void onScaleEnd(ScaleGestureDetector detector) {
     }
 
-    public void moveToUpperLeft() {
+    public void moveToLeft() {
         if (getWidth() == 0 || getHeight() == 0) {
             final ViewTreeObserver observer = getViewTreeObserver();
             observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                     public void onGlobalLayout() {
-                        moveToUpperLeft();
+                        moveToLeft();
                         getViewTreeObserver().removeOnGlobalLayoutListener(this);
                     }
                 });
@@ -154,7 +155,6 @@
         getEdgesHelper(edges);
         final float scale = mRenderer.scale;
         mRenderer.centerX += Math.ceil(edges.left / scale);
-        mRenderer.centerY += Math.ceil(edges.top / scale);
     }
 
     public void setTouchEnabled(boolean enabled) {
@@ -197,11 +197,13 @@
             float squaredDist = (mFirstX - x) * (mFirstX - x) + (mFirstY - y) * (mFirstY - y);
             float slop = config.getScaledTouchSlop() * config.getScaledTouchSlop();
             long now = System.currentTimeMillis();
-            // only do this if it's a small movement
-            if (mTouchCallback != null &&
-                    squaredDist < slop &&
+            if (mTouchCallback != null) {
+                // only do this if it's a small movement
+                if (squaredDist < slop &&
                     now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
-                mTouchCallback.onTap();
+                    mTouchCallback.onTap();
+                }
+                mTouchCallback.onTouchUp();
             }
         }
 
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/TranslucentDecor.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/TranslucentDecor.java
new file mode 100644
index 0000000..9ce7331
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/TranslucentDecor.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+/* Copied from Launcher3 */
+package com.android.wallpapercropper;
+
+import android.app.Activity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+
+public class TranslucentDecor {
+    private static final int SYSTEM_UI_FLAG_TRANSPARENT_STATUS = 0x00001000;
+    private static final int SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION = 0x00002000;
+
+    // Replace with SDK constants when available.
+    public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;
+    public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000;
+
+    // Behave properly on early K builds.
+    public static final boolean SYSUI_SUPPORTED = !hasSystemUiFlag("ALLOW_TRANSIENT") &&
+            hasSystemUiFlag("TRANSPARENT_STATUS") &&
+            hasSystemUiFlag("TRANSPARENT_NAVIGATION");
+
+    public static final boolean WM_SUPPORTED =
+            hasWindowManagerFlag("TRANSLUCENT_STATUS") &&
+            hasWindowManagerFlag("TRANSLUCENT_NAVIGATION");
+
+    private final View mTarget;
+
+    public TranslucentDecor(View target) {
+        mTarget = target;
+    }
+
+    public void requestTranslucentDecor(boolean translucent) {
+        int sysui = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+        if (WM_SUPPORTED && mTarget.getContext() instanceof Activity) {
+            Window w = ((Activity) mTarget.getContext()).getWindow();
+            int wmFlags = FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION;
+            if (translucent) {
+                w.addFlags(wmFlags);
+            } else {
+               w.clearFlags(wmFlags);
+            }
+        } else if (SYSUI_SUPPORTED) {  // Remove when droidfood platform is updated
+            if (translucent) {
+                sysui |= SYSTEM_UI_FLAG_TRANSPARENT_STATUS | SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION;
+            }
+        }
+        mTarget.setSystemUiVisibility(sysui);
+    }
+
+    private static boolean hasWindowManagerFlag(String name) {
+        try {
+            return WindowManager.LayoutParams.class.getField("FLAG_" + name) != null;
+        } catch (NoSuchFieldException e) {
+            return false;
+        }
+    }
+
+    private static boolean hasSystemUiFlag(String name) {
+        try {
+            return View.class.getField("SYSTEM_UI_FLAG_" + name) != null;
+        } catch (NoSuchFieldException e) {
+            return false;
+        }
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index af48652..48fbcc5 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -75,6 +75,9 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         init();
+        if (!enableRotation()) {
+            setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
+        }
     }
 
     protected void init() {
@@ -99,6 +102,12 @@
                         cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone);
                     }
                 });
+        TranslucentDecor transparentDecor = new TranslucentDecor(findViewById(R.id.wallpaper_root));
+        transparentDecor.requestTranslucentDecor(true);
+    }
+
+    public boolean enableRotation() {
+        return getResources().getBoolean(R.bool.allow_rotation);
     }
 
     public static String getSharedPreferencesKey() {
@@ -162,7 +171,6 @@
     }
 
     protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
-
         BitmapCropTask cropTask = new BitmapCropTask(this,
                 filePath, null, 0, 0, true, false, null);
         final Point bounds = cropTask.getImageBounds();
@@ -200,7 +208,7 @@
                 }
             }
         };
-        BitmapCropTask cropTask = new BitmapCropTask(res, resId,
+        BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
                 crop, outSize.x, outSize.y,
                 true, false, onEndCrop);
         cropTask.execute();
@@ -213,9 +221,11 @@
 
     protected void cropImageAndSetWallpaper(Uri uri,
             OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
-     // Get the crop
+        // Get the crop
         Point inSize = mCropView.getSourceDimensions();
 
+        boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
+
         Point minDims = new Point();
         Point maxDims = new Point();
         Display d = getWindowManager().getDefaultDisplay();
@@ -226,12 +236,12 @@
 
         int maxDim = Math.max(maxDims.x, maxDims.y);
         final int minDim = Math.min(minDims.x, minDims.y);
-        int defaultWidth;
+        int defaultWallpaperWidth;
         if (isScreenLarge(getResources())) {
-            defaultWidth = (int) (maxDim *
+            defaultWallpaperWidth = (int) (maxDim *
                     wallpaperTravelToScreenWidthRatio(maxDim, minDim));
         } else {
-            defaultWidth = Math.max((int)
+            defaultWallpaperWidth = Math.max((int)
                     (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
         }
 
@@ -256,12 +266,17 @@
 
         // ADJUST CROP WIDTH
         // Extend the crop all the way to the right, for parallax
-        float extraSpaceToRight = inSize.x - cropRect.right;
+        // (or all the way to the left, in RTL)
+        float extraSpace = ltr ? inSize.x - cropRect.right : cropRect.left;
         // Cap the amount of extra width
-        float maxExtraSpace = defaultWidth / cropScale - cropRect.width();
-        extraSpaceToRight = Math.min(extraSpaceToRight, maxExtraSpace);
+        float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
+        extraSpace = Math.min(extraSpace, maxExtraSpace);
 
-        cropRect.right += extraSpaceToRight;
+        if (ltr) {
+            cropRect.right += extraSpace;
+        } else {
+            cropRect.left -= extraSpace;
+        }
 
         // ADJUST CROP HEIGHT
         if (isPortrait) {
@@ -287,7 +302,7 @@
                 }
             }
         };
-        BitmapCropTask cropTask = new BitmapCropTask(uri,
+        BitmapCropTask cropTask = new BitmapCropTask(this, uri,
                 cropRect, outWidth, outHeight, true, false, onEndCrop);
         if (onBitmapCroppedHandler != null) {
             cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
@@ -299,7 +314,7 @@
         public void onBitmapCropped(byte[] imageBytes);
     }
 
-    protected class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
+    protected static class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
         Uri mInUri = null;
         Context mContext;
         String mInFilePath;
@@ -309,7 +324,6 @@
         RectF mCropBounds = null;
         int mOutWidth, mOutHeight;
         int mRotation = 0; // for now
-        protected final WallpaperManager mWPManager;
         String mOutputFormat = "jpg"; // for now
         boolean mSetWallpaper;
         boolean mSaveCroppedBitmap;
@@ -324,7 +338,6 @@
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mContext = c;
             mInFilePath = filePath;
-            mWPManager = WallpaperManager.getInstance(getApplicationContext());
             init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
@@ -332,24 +345,23 @@
                 RectF cropBounds, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mInImageBytes = imageBytes;
-            mWPManager = WallpaperManager.getInstance(getApplicationContext());
             init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
-        public BitmapCropTask(Uri inUri,
+        public BitmapCropTask(Context c, Uri inUri,
                 RectF cropBounds, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mContext = c;
             mInUri = inUri;
-            mWPManager = WallpaperManager.getInstance(getApplicationContext());
             init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
-        public BitmapCropTask(Resources res, int inResId,
+        public BitmapCropTask(Context c, Resources res, int inResId,
                 RectF cropBounds, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mContext = c;
             mInResId = inResId;
             mResources = res;
-            mWPManager = WallpaperManager.getInstance(getApplicationContext());
             init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
@@ -385,7 +397,7 @@
                 try {
                     if (mInUri != null) {
                         mInStream = new BufferedInputStream(
-                                getContentResolver().openInputStream(mInUri));
+                                mContext.getContentResolver().openInputStream(mInUri));
                     } else if (mInFilePath != null) {
                         mInStream = mContext.openFileInput(mInFilePath);
                     } else if (mInImageBytes != null) {
@@ -426,16 +438,17 @@
 
             regenerateInputStream();
 
-            if (mNoCrop && mInStream != null) {
+            WallpaperManager wallpaperManager = null;
+            if (mSetWallpaper) {
+                wallpaperManager = WallpaperManager.getInstance(mContext.getApplicationContext());
+            }
+            if (mSetWallpaper && mNoCrop && mInStream != null) {
                 try {
-                    mWPManager.setStream(mInStream);
+                    wallpaperManager.setStream(mInStream);
                 } catch (IOException e) {
                     Log.w(LOGTAG, "cannot write stream to wallpaper", e);
                     failure = true;
                 }
-                if (mOnEndRunnable != null) {
-                    mOnEndRunnable.run();
-                }
                 return !failure;
             }
             if (mInStream != null) {
@@ -509,7 +522,9 @@
                             (int) returnRect.height(), Bitmap.Config.ARGB_8888);
                     if (tmp != null) {
                         Canvas c = new Canvas(tmp);
-                        c.drawBitmap(crop, m, new Paint());
+                        Paint p = new Paint();
+                        p.setFilterBitmap(true);
+                        c.drawBitmap(crop, m, p);
                         crop = tmp;
                     }
                 } else if (mRotation > 0) {
@@ -534,26 +549,18 @@
                 ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
                 if (crop.compress(cf, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
                     // If we need to set to the wallpaper, set it
-                    if (mSetWallpaper && mWPManager != null) {
-                        if (mWPManager == null) {
-                            Log.w(LOGTAG, "no wallpaper manager");
-                            failure = true;
-                        } else {
-                            try {
-                                byte[] outByteArray = tmpOut.toByteArray();
-                                mWPManager.setStream(new ByteArrayInputStream(outByteArray));
-                                if (mOnBitmapCroppedHandler != null) {
-                                    mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
-                                }
-                            } catch (IOException e) {
-                                Log.w(LOGTAG, "cannot write stream to wallpaper", e);
-                                failure = true;
+                    if (mSetWallpaper && wallpaperManager != null) {
+                        try {
+                            byte[] outByteArray = tmpOut.toByteArray();
+                            wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
+                            if (mOnBitmapCroppedHandler != null) {
+                                mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
                             }
+                        } catch (IOException e) {
+                            Log.w(LOGTAG, "cannot write stream to wallpaper", e);
+                            failure = true;
                         }
                     }
-                    if (mOnEndRunnable != null) {
-                        mOnEndRunnable.run();
-                    }
                 } else {
                     Log.w(LOGTAG, "cannot compress bitmap");
                     failure = true;
@@ -569,8 +576,9 @@
 
         @Override
         protected void onPostExecute(Boolean result) {
-            setResult(Activity.RESULT_OK);
-            finish();
+            if (mOnEndRunnable != null) {
+                mOnEndRunnable.run();
+            }
         }
     }
 
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 27ca7a0..b69a0c8 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -25,6 +25,7 @@
 import java.util.List;
 
 import android.os.Handler;
+import android.os.Looper;
 import android.util.ArrayMap;
 import com.android.internal.app.ProcessStats;
 import com.android.internal.os.BatteryStatsImpl;
@@ -166,7 +167,8 @@
 
         static final int MSG_BG_START_TIMEOUT = 1;
 
-        ServiceMap(int userId) {
+        ServiceMap(Looper looper, int userId) {
+            super(looper);
             mUserId = userId;
         }
 
@@ -255,7 +257,7 @@
     private ServiceMap getServiceMap(int callingUser) {
         ServiceMap smap = mServiceMap.get(callingUser);
         if (smap == null) {
-            smap = new ServiceMap(callingUser);
+            smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
             mServiceMap.put(callingUser, smap);
         }
         return smap;
@@ -2417,7 +2419,11 @@
             int[] users = mAm.getUsersLocked();
             if ("all".equals(name)) {
                 for (int user : users) {
-                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(user);
+                    ServiceMap smap = mServiceMap.get(user);
+                    if (smap == null) {
+                        continue;
+                    }
+                    ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
                     for (int i=0; i<alls.size(); i++) {
                         ServiceRecord r1 = alls.valueAt(i);
                         services.add(r1);
@@ -2438,7 +2444,11 @@
                 }
 
                 for (int user : users) {
-                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(user);
+                    ServiceMap smap = mServiceMap.get(user);
+                    if (smap == null) {
+                        continue;
+                    }
+                    ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
                     for (int i=0; i<alls.size(); i++) {
                         ServiceRecord r1 = alls.valueAt(i);
                         if (componentName != null) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index fe91b6c..1987d04 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -226,7 +226,7 @@
     static final boolean DEBUG_RESULTS = localLOGV || false;
     static final boolean DEBUG_SERVICE = localLOGV || false;
     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
-    static final boolean DEBUG_STACK = localLOGV || false;
+    static final boolean DEBUG_STACK = localLOGV || true;
     static final boolean DEBUG_SWITCH = localLOGV || false;
     static final boolean DEBUG_TASKS = localLOGV || false;
     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 2798104..afa4f78 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -24,6 +24,7 @@
 import android.app.ActivityManager.StackBoxInfo;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.Debug;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -322,7 +323,8 @@
      * @return true if a change was made, false otherwise.
      */
     boolean moveHomeStackBox(boolean toTop) {
-        if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop);
+        if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop + " Callers=" +
+                Debug.getCallers(4));
         switch (mStackBoxes.size()) {
             case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!");
             case 1: return false; // Only the home StackBox exists.
diff --git a/services/java/com/android/server/wm/FocusedStackFrame.java b/services/java/com/android/server/wm/FocusedStackFrame.java
index 365b277..cc48b86 100644
--- a/services/java/com/android/server/wm/FocusedStackFrame.java
+++ b/services/java/com/android/server/wm/FocusedStackFrame.java
@@ -63,7 +63,7 @@
     }
 
     private void draw(Rect bounds, int color) {
-        if (DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
+        if (false && DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
                 " color=" + Integer.toHexString(color));
         mTmpDrawRect.set(bounds);
         Canvas c = null;
@@ -100,7 +100,7 @@
     }
 
     private void positionSurface(Rect bounds) {
-        if (DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
+        if (false && DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
         mSurfaceControl.setSize(bounds.width(), bounds.height());
         mSurfaceControl.setPosition(bounds.left, bounds.top);
     }
@@ -108,7 +108,7 @@
     // Note: caller responsible for being inside
     // Surface.openTransaction() / closeTransaction()
     public void setVisibility(boolean on) {
-        if (DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
+        if (false && DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
                 " mLastBounds=" + mLastBounds.toShortString() +
                 " mBounds=" + mBounds.toShortString());
         if (mSurfaceControl == null) {
@@ -132,7 +132,7 @@
     }
 
     public void setBounds(Rect bounds) {
-        if (DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
+        if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
         mBounds.set(bounds);
     }
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 36b34f8..e089ca6 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -187,7 +187,7 @@
     static final boolean DEBUG_SURFACE_TRACE = false;
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
-    static final boolean DEBUG_STACK = false;
+    static final boolean DEBUG_STACK = true;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -2367,10 +2367,10 @@
         }
 
         if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
-            TAG, "Remove " + win + " client="
-            + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
-            + ", surface=" + win.mWinAnimator.mSurfaceControl,
-            new RuntimeException("here").fillInStackTrace());
+                TAG, "Remove " + win + " client="
+                + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
+                + ", surface=" + win.mWinAnimator.mSurfaceControl + " Callers="
+                + Debug.getCallers(4));
 
         final long origId = Binder.clearCallingIdentity();
 
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 52ebaf0..f2e5254 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -636,6 +636,30 @@
     return false;
 }
 
+/*
+ * A simple container that holds a resource type and name. It is ordered first by type then
+ * by name.
+ */
+struct type_ident_pair_t {
+    String16 type;
+    String16 ident;
+
+    type_ident_pair_t() { };
+    type_ident_pair_t(const String16& t, const String16& i) : type(t), ident(i) { }
+    type_ident_pair_t(const type_ident_pair_t& o) : type(o.type), ident(o.ident) { }
+    inline bool operator < (const type_ident_pair_t& o) const {
+        int cmp = compare_type(type, o.type);
+        if (cmp < 0) {
+            return true;
+        } else if (cmp > 0) {
+            return false;
+        } else {
+            return strictly_order_type(ident, o.ident);
+        }
+    }
+};
+
+
 status_t parseAndAddEntry(Bundle* bundle,
                         const sp<AaptFile>& in,
                         ResXMLTree* block,
@@ -650,6 +674,7 @@
                         const String16& product,
                         bool pseudolocalize,
                         const bool overwrite,
+                        KeyedVector<type_ident_pair_t, bool>* skippedResourceNames,
                         ResourceTable* outTable)
 {
     status_t err;
@@ -684,6 +709,13 @@
 
         if (bundleProduct[0] == '\0') {
             if (strcmp16(String16("default").string(), product.string()) != 0) {
+                /*
+                 * This string has a product other than 'default'. Do not add it,
+                 * but record it so that if we do not see the same string with
+                 * product 'default' or no product, then report an error.
+                 */
+                skippedResourceNames->replaceValueFor(
+                        type_ident_pair_t(curType, ident), true);
                 return NO_ERROR;
             }
         } else {
@@ -797,6 +829,11 @@
 
     DefaultKeyedVector<String16, uint32_t> nextPublicId(0);
 
+    // Stores the resource names that were skipped. Typically this happens when
+    // AAPT is invoked without a product specified and a resource has no
+    // 'default' product attribute.
+    KeyedVector<type_ident_pair_t, bool> skippedResourceNames;
+
     ResXMLTree::event_code_t code;
     do {
         code = block.next();
@@ -1544,7 +1581,7 @@
 
                 err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
                         *curTag, curIsStyled, curFormat, curIsFormatted,
-                        product, false, overwrite, outTable);
+                        product, false, overwrite, &skippedResourceNames, outTable);
 
                 if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
                     hasErrors = localHasErrors = true;
@@ -1557,7 +1594,7 @@
                         err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
                                 ident, *curTag, curIsStyled, curFormat,
                                 curIsFormatted, product,
-                                true, overwrite, outTable);
+                                true, overwrite, &skippedResourceNames, outTable);
                         if (err != NO_ERROR) {
                             hasErrors = localHasErrors = true;
                         }
@@ -1596,6 +1633,30 @@
         }
     }
 
+    // For every resource defined, there must be exist one variant with a product attribute
+    // set to 'default' (or no product attribute at all).
+    // We check to see that for every resource that was ignored because of a mismatched
+    // product attribute, some product variant of that resource was processed.
+    for (size_t i = 0; i < skippedResourceNames.size(); i++) {
+        if (skippedResourceNames[i]) {
+            const type_ident_pair_t& p = skippedResourceNames.keyAt(i);
+            if (!outTable->hasBagOrEntry(myPackage, p.type, p.ident)) {
+                const char* bundleProduct =
+                        (bundle->getProduct() == NULL) ? "" : bundle->getProduct();
+                fprintf(stderr, "In resource file %s: %s\n",
+                        in->getPrintableSource().string(),
+                        curParams.toString().string());
+
+                fprintf(stderr, "\t%s '%s' does not match product %s.\n"
+                        "\tYou may have forgotten to include a 'default' product variant"
+                        " of the resource.\n",
+                        String8(p.type).string(), String8(p.ident).string(),
+                        bundleProduct[0] == 0 ? "default" : bundleProduct);
+                return UNKNOWN_ERROR;
+            }
+        }
+    }
+
     return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
 }
 
@@ -2483,8 +2544,8 @@
                     
                     String16 comment(c->getComment());
                     typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
-                    //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(),
-                    //     String8(comment).string());
+                    //printf("Type symbol [%08x] %s comment: %s\n", rid,
+                    //        String8(c->getName()).string(), String8(comment).string());
                     comment = c->getTypeComment();
                     typeSymbols->appendTypeComment(String8(c->getName()), comment);
                 } else {